use warnings;
use Test::More;
use Email::MIME;
-use Email::Filter;
use File::Temp qw/tempdir/;
use Cwd;
-use IPC::Run qw(run);
use PublicInbox::MID qw(mid2path);
+eval { require IPC::Run };
+plan skip_all => "missing IPC::Run for t/mda.t" if $@;
my $mda = "blib/script/public-inbox-mda";
my $learn = "blib/script/public-inbox-learn";
my $fail_path = "$fail_bin:$ENV{PATH}"; # for spamc spam mock
my $addr = 'test-public@example.com';
my $cfgpfx = "publicinbox.test";
-my $failbox = "$home/fail.mbox";
+my $faildir = "$home/faildir/";
my $mime;
{
open(my $fh, '<', $mbox) or die "failed to open mbox: $mbox\n";
my $str = eval { local $/; <$fh> };
close $fh;
- my $msg = Email::Filter->new(data => $str);
- $msg = Email::MIME->new($msg->simple->as_string);
+ my $msg = Email::MIME->new($str);
my $from = $msg->header('From');
- my $author = PublicInbox::Address::from_name($from);
+ my ($author) = PublicInbox::Address::names($from);
my ($email) = PublicInbox::Address::emails($from);
my $date = $msg->header('Date');
{
my $good_rev;
- local $ENV{PI_EMERGENCY} = $failbox;
+ local $ENV{PI_EMERGENCY} = $faildir;
local $ENV{HOME} = $home;
local $ENV{ORIGINAL_RECIPIENT} = $addr;
my $simple = Email::Simple->new(<<EOF);
# ensure successful message delivery
{
local $ENV{PATH} = $main_path;
- run([$mda], \$in);
+ IPC::Run::run([$mda], \$in);
my $rev = `git --git-dir=$maindir rev-list HEAD`;
like($rev, qr/\A[a-f0-9]{40}/, "good revision committed");
chomp $rev;
# ensure failures work, fail with bad spamc
{
- ok(!-e $failbox, "nothing in PI_EMERGENCY before");
+ my @prev = <$faildir/new/*>;
+ is(scalar @prev, 0 , "nothing in PI_EMERGENCY before");
local $ENV{PATH} = $fail_path;
- run([$mda], \$in);
+ IPC::Run::run([$mda], \$in);
my @revs = `git --git-dir=$maindir rev-list HEAD`;
is(scalar @revs, 1, "bad revision not committed");
- ok(-s $failbox > 0, "PI_EMERGENCY is written to");
+ my @new = <$faildir/new/*>;
+ is(scalar @new, 1, "PI_EMERGENCY is written to");
}
fail_bad_header($good_rev, "bad recipient", <<"");
# spam training
{
- local $ENV{PI_EMERGENCY} = $failbox;
+ local $ENV{PI_EMERGENCY} = $faildir;
local $ENV{HOME} = $home;
local $ENV{ORIGINAL_RECIPIENT} = $addr;
local $ENV{PATH} = $main_path;
{
# deliver the spam message, first
- run([$mda], \$in);
+ IPC::Run::run([$mda], \$in);
my $path = mid2path($mid);
my $msg = `git --git-dir=$maindir cat-file blob HEAD:$path`;
like($msg, qr/\Q$mid\E/, "message delivered");
# now train it
local $ENV{GIT_AUTHOR_EMAIL} = 'trainer@example.com';
local $ENV{GIT_COMMITTER_EMAIL} = 'trainer@example.com';
- run([$learn, "spam"], \$msg);
+ IPC::Run::run([$learn, "spam"], \$msg);
is($?, 0, "no failure from learning spam");
- run([$learn, "spam"], \$msg);
+ IPC::Run::run([$learn, "spam"], \$msg);
is($?, 0, "no failure from learning spam idempotently");
}
}
# train ham message
{
- local $ENV{PI_EMERGENCY} = $failbox;
+ local $ENV{PI_EMERGENCY} = $faildir;
local $ENV{HOME} = $home;
local $ENV{ORIGINAL_RECIPIENT} = $addr;
local $ENV{PATH} = $main_path;
local $ENV{GIT_AUTHOR_EMAIL} = 'trainer@example.com';
local $ENV{GIT_COMMITTER_EMAIL} = 'trainer@example.com';
- run([$learn, "ham"], \$in);
+ IPC::Run::run([$learn, "ham"], \$in);
is($?, 0, "learned ham without failure");
my $path = mid2path($mid);
my $msg = `git --git-dir=$maindir cat-file blob HEAD:$path`;
like($msg, qr/\Q$mid\E/, "ham message delivered");
- run([$learn, "ham"], \$in);
+ IPC::Run::run([$learn, "ham"], \$in);
is($?, 0, "learned ham idempotently ");
# ensure trained email is filtered, too
{
$in = $mime->as_string;
- run([$learn, "ham"], \$in);
+ IPC::Run::run([$learn, "ham"], \$in);
is($?, 0, "learned ham without failure");
my $path = mid2path($mid);
$msg = `git --git-dir=$maindir cat-file blob HEAD:$path`;
}
}
-# faildir - emergency destination is maildir
-{
- my $faildir= "$home/faildir/";
- local $ENV{PI_EMERGENCY} = $faildir;
- local $ENV{HOME} = $home;
- local $ENV{ORIGINAL_RECIPIENT} = $addr;
- local $ENV{PATH} = $fail_path;
- my $in = <<EOF;
-From: Faildir <faildir\@example.com>
-To: You <you\@example.com>
-Cc: $addr
-Message-ID: <faildir\@example.com>
-Subject: faildir subject
-Date: Thu, 01 Jan 1970 00:00:00 +0000
-
-EOF
- run([$mda], \$in);
- ok(-d $faildir, "emergency exists");
- my @new = glob("$faildir/new/*");
- is(scalar(@new), 1, "message delivered");
- is(unlink(@new), 1, "removed emergency message");
-
- local $ENV{PATH} = $main_path;
- $in = <<EOF;
-From: Faildir <faildir\@example.com>
-To: $addr
-Content-Type: text/html
-Message-ID: <faildir\@example.com>
-Subject: faildir subject
-Date: Thu, 01 Jan 1970 00:00:00 +0000
-
-<html><body>bad</body></html>
-EOF
- my $out = '';
- my $err = '';
- run([$mda], \$in, \$out, \$err);
- isnt($?, 0, "mda exited with failure");
- is(length $out, 0, 'nothing in stdout');
- isnt(length $err, 0, 'error message in stderr');
-
- @new = glob("$faildir/new/*");
- is(scalar(@new), 0, "new message did not show up");
-
- # reject multipart again
- $in = $mime->as_string;
- $err = '';
- run([$mda], \$in, \$out, \$err);
- isnt($?, 0, "mda exited with failure");
- is(length $out, 0, 'nothing in stdout');
- isnt(length $err, 0, 'error message in stderr');
- @new = glob("$faildir/new/*");
- is(scalar(@new), 0, "new message did not show up");
-}
-
done_testing();
sub fail_bad_header {
my ($good_rev, $msg, $in) = @_;
- open my $fh, '>', $failbox or die "failed to open $failbox: $!\n";
- close $fh or die "failed to close $failbox: $!\n";
+ my @f = glob("$faildir/*/*");
+ unlink @f if @f;
my ($out, $err) = ("", "");
local $ENV{PATH} = $main_path;
- run([$mda], \$in, \$out, \$err);
+ IPC::Run::run([$mda], \$in, \$out, \$err);
my $rev = `git --git-dir=$maindir rev-list HEAD`;
chomp $rev;
is($rev, $good_rev, "bad revision not commited ($msg)");
- ok(-s $failbox > 0, "PI_EMERGENCY is written to ($msg)");
+ @f = glob("$faildir/*/*");
+ is(scalar @f, 1, "faildir written to");
[ $in, $out, $err ];
}