user/dev discussion of public-inbox itself
 help / color / mirror / code / Atom feed
From: Eric Wong <e@yhbt.net>
To: meta@public-inbox.org
Subject: [PATCH 1/3] testcommon: introduce mime_load sub
Date: Sat, 25 Apr 2020 05:52:21 +0000	[thread overview]
Message-ID: <20200425055223.21879-2-e@yhbt.net> (raw)
In-Reply-To: <20200425055223.21879-1-e@yhbt.net>

We'll use this to create, memoize, and reuse .eml files.  This
will be used to reduce (and eventually eliminate) our dependency
on Email::MIME in tests.
---
 lib/PublicInbox/TestCommon.pm | 25 ++++++++++++++++++++++++-
 t/filter_base.t               | 12 +++++++-----
 t/filter_mirror.t             |  9 +++++----
 t/mda.t                       |  5 +++--
 t/msg_iter.t                  | 10 +++++++---
 t/plack.t                     | 20 ++++++++++++--------
 t/psgi_attach.t               | 13 ++++---------
 t/psgi_v2.t                   |  5 +++--
 t/search.t                    |  6 ++++--
 9 files changed, 69 insertions(+), 36 deletions(-)

diff --git a/lib/PublicInbox/TestCommon.pm b/lib/PublicInbox/TestCommon.pm
index b50871e8..ac14d27b 100644
--- a/lib/PublicInbox/TestCommon.pm
+++ b/lib/PublicInbox/TestCommon.pm
@@ -9,7 +9,30 @@ 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 xsys xqx);
+	run_script start_script key2sub xsys xqx mime_load);
+
+sub mime_load ($;&) {
+	my ($path, $cb) = @_;
+	if (open(my $fh, '<', $path)) {
+		PublicInbox::MIME->new(\(do { local $/; <$fh> }));
+	} elsif ($cb) {
+		require File::Temp;
+
+		my $mime = $cb->();
+		my ($dir) = ($path =~ m!(.+)/(?:[^/]+)\z!);
+		-d $dir or die "BUG: dir=$dir is not the dir of $path";
+		my $fh = File::Temp->new(DIR => $dir);
+		$fh->autoflush(1);
+		print $fh $mime->as_string or die "print: $!";
+		my $fn = $fh->filename;
+		rename($fn, $path) or die "link $fn => $path: $!";
+		$fh->unlink_on_destroy(0);
+		pop @_; # retry via tail recursion
+		goto &mime_load;
+	} else {
+		die "open $path: $!";
+	}
+}
 
 sub tmpdir (;$) {
 	my ($base) = @_;
diff --git a/t/filter_base.t b/t/filter_base.t
index f25d2dd7..7919dd65 100644
--- a/t/filter_base.t
+++ b/t/filter_base.t
@@ -3,7 +3,7 @@
 use strict;
 use warnings;
 use Test::More;
-use Email::MIME;
+use PublicInbox::TestCommon;
 use_ok 'PublicInbox::Filter::Base';
 
 {
@@ -21,6 +21,7 @@ use_ok 'PublicInbox::Filter::Base';
 
 {
 	my $f = PublicInbox::Filter::Base->new;
+	my $email = mime_load 't/filter_base-xhtml.eml', sub {
 	my $html_body = "<html><body>hi</body></html>";
 	my $parts = [
 		Email::MIME->create(
@@ -38,19 +39,20 @@ use_ok 'PublicInbox::Filter::Base';
 			body => 'hi = "bye"',
 		)
 	];
-	my $email = Email::MIME->create(
+	Email::MIME->create(
 		header_str => [
 		  From => 'a@example.com',
 		  Subject => 'blah',
 		  'Content-Type' => 'multipart/alternative'
 		],
 		parts => $parts,
-	);
+	)}; # mime_load sub
 	is($f->delivery($email), 100, "xhtml rejected");
 }
 
 {
 	my $f = PublicInbox::Filter::Base->new;
+	my $email = mime_load 't/filter_base-junk.eml', sub {
 	my $parts = [
 		Email::MIME->create(
 			attributes => {
@@ -67,14 +69,14 @@ use_ok 'PublicInbox::Filter::Base';
 			body => 'junk',
 		)
 	];
-	my $email = Email::MIME->create(
+	Email::MIME->create(
 		header_str => [
 		  From => 'a@example.com',
 		  Subject => 'blah',
 		  'Content-Type' => 'multipart/mixed'
 		],
 		parts => $parts,
-	);
+	)}; # mime_load sub
 	is($f->delivery($email), 100, 'proprietary format rejected on glob');
 }
 
diff --git a/t/filter_mirror.t b/t/filter_mirror.t
index b1946146..694209d9 100644
--- a/t/filter_mirror.t
+++ b/t/filter_mirror.t
@@ -3,12 +3,13 @@
 use strict;
 use warnings;
 use Test::More;
-use Email::MIME;
+use PublicInbox::TestCommon;
 use_ok 'PublicInbox::Filter::Mirror';
 
 my $f = PublicInbox::Filter::Mirror->new;
 ok($f, 'created PublicInbox::Filter::Mirror object');
 {
+	my $email = mime_load 't/filter_mirror.eml', sub {
 	my $html_body = "<html><body>hi</body></html>";
 	my $parts = [
 		Email::MIME->create(
@@ -26,15 +27,15 @@ ok($f, 'created PublicInbox::Filter::Mirror object');
 			body => 'hi = "bye"',
 		)
 	];
-	my $email = Email::MIME->create(
+	Email::MIME->create(
 		header_str => [
 		  From => 'a@example.com',
 		  Subject => 'blah',
 		  'Content-Type' => 'multipart/alternative'
 		],
 		parts => $parts,
-	);
+	)}; # mime_laod sub
 	is($f->ACCEPT, $f->delivery($email), 'accept any trash that comes');
 }
 
-done_testing();
+ done_testing();
diff --git a/t/mda.t b/t/mda.t
index fb505146..5457f17f 100644
--- a/t/mda.t
+++ b/t/mda.t
@@ -233,6 +233,7 @@ EOF
 		"learned ham idempotently ");
 
 	# ensure trained email is filtered, too
+	$mime = mime_load 't/mda-mime.eml', sub {
 	my $html_body = "<html><body>hi</body></html>";
 	my $parts = [
 		Email::MIME->create(
@@ -251,7 +252,7 @@ EOF
 		)
 	];
 	$mid = 'multipart-html-sucks@11';
-	$mime = Email::MIME->create(
+	Email::MIME->create(
 		header_str => [
 		  From => 'a@example.com',
 		  Subject => 'blah',
@@ -260,7 +261,7 @@ EOF
 		  'Content-Type' => 'multipart/alternative',
 		],
 		parts => $parts,
-	);
+	)}; # mime_load sub
 
 	{
 		$in = $mime->as_string;
diff --git a/t/msg_iter.t b/t/msg_iter.t
index 573ee412..ac2066a2 100644
--- a/t/msg_iter.t
+++ b/t/msg_iter.t
@@ -3,16 +3,18 @@
 use strict;
 use warnings;
 use Test::More;
-use Email::MIME;
+use PublicInbox::TestCommon;
 use PublicInbox::Hval qw(ascii_html);
 use PublicInbox::InboxWritable;
 use_ok('PublicInbox::MsgIter');
 
 {
+	my $mime = mime_load 't/msg_iter-order.eml', sub {
 	my $parts = [ Email::MIME->create(body => "a\n"),
 			Email::MIME->create(body => "b\n") ];
-	my $mime = Email::MIME->create(parts => $parts,
+	Email::MIME->create(parts => $parts,
 				header_str => [ From => 'root@localhost' ]);
+	}; # mime_load sub
 	my @parts;
 	msg_iter($mime, sub {
 		my ($part, $level, @ex) = @{$_[0]};
@@ -24,13 +26,15 @@ use_ok('PublicInbox::MsgIter');
 }
 
 {
+	my $mime = mime_load 't/msg_iter-nested.eml', sub {
 	my $parts = [ Email::MIME->create(body => 'a'),
 			Email::MIME->create(body => 'b') ];
 	$parts = [ Email::MIME->create(parts => $parts,
 				header_str => [ From => 'sub@localhost' ]),
 			Email::MIME->create(body => 'sig') ];
-	my $mime = Email::MIME->create(parts => $parts,
+	Email::MIME->create(parts => $parts,
 				header_str => [ From => 'root@localhost' ]);
+	}; # mime_load sub
 	my @parts;
 	msg_iter($mime, sub {
 		my ($part, $level, @ex) = @{$_[0]};
diff --git a/t/plack.t b/t/plack.t
index b16bc8de..d45dbcd2 100644
--- a/t/plack.t
+++ b/t/plack.t
@@ -52,11 +52,12 @@ EOF
 
 	# multipart with two text bodies
 	my %attr_text = (attributes => { content_type => 'text/plain' });
+	$mime = mime_load 't/plack-2-txt-bodies.eml', sub {
 	my $parts = [
 		Email::MIME->create(%attr_text, body => 'hi'),
 		Email::MIME->create(%attr_text, body => 'bye')
 	];
-	$mime = Email::MIME->create(
+	Email::MIME->create(
 		header_str => [
 			From => 'a@example.com',
 			Subject => 'blargh',
@@ -64,11 +65,13 @@ EOF
 			'In-Reply-To' => '<irp@example.com>'
 		],
 		parts => $parts,
-	);
+	)}; # mime_load sub
 	$im->add($mime);
 
 	# multipart with attached patch + filename
-	$parts = [ Email::MIME->create(%attr_text, body => 'hi, see attached'),
+	$mime = mime_load 't/plack-attached-patch.eml', sub {
+	my $parts = [
+		Email::MIME->create(%attr_text, body => 'hi, see attached'),
 		Email::MIME->create(
 			attributes => {
 					content_type => 'text/plain',
@@ -78,18 +81,19 @@ EOF
 				"@@ -49, 7 +49,34 @@\n"
 			)
 	];
-	$mime = Email::MIME->create(
+	Email::MIME->create(
 		header_str => [
 			From => 'a@example.com',
 			Subject => '[PATCH] asdf',
 			'Message-ID' => '<patch@example.com>'
 		],
 		parts => $parts
-	);
+	)}; # mime_load sub
 	$im->add($mime);
 
 	# multipart collapsed to single quoted-printable text/plain
-	$parts = [
+	$mime = mime_load 't/plack-qp.eml', sub {
+	my $parts = [
 		Email::MIME->create(
 			attributes => {
 				content_type => 'text/plain',
@@ -98,14 +102,14 @@ EOF
 			body => 'hi = bye',
 		)
 	];
-	$mime = Email::MIME->create(
+	Email::MIME->create(
 		header_str => [
 			From => 'qp@example.com',
 			Subject => 'QP',
 			'Message-ID' => '<qp@example.com>',
 			],
 		parts => $parts,
-	);
+	)};
 	like($mime->body_raw, qr/hi =3D bye=/, 'our test used QP correctly');
 	$im->add($mime);
 
diff --git a/t/psgi_attach.t b/t/psgi_attach.t
index 2376bba7..0dde9323 100644
--- a/t/psgi_attach.t
+++ b/t/psgi_attach.t
@@ -26,13 +26,11 @@ my $im = PublicInbox::Import->new($git, 'test', $addr);
 $im->init_bare;
 
 {
-	open my $fh, '<', '/dev/urandom' or die "unable to open urandom: $!\n";
-	sysread($fh, my $buf, 8);
-	is(8, length($buf), 'read some random data');
 	my $qp = "abcdef=g\n==blah\n";
-	my $b64 = 'b64'.$buf."\n";
+	my $b64 = "b64\xde\xad\xbe\xef\n";
 	my $txt = "plain\ntext\npass\nthrough\n";
 	my $dot = "dotfile\n";
+	my $mime = mime_load 't/psgi_attach.eml', sub {
 	my $parts = [
 		Email::MIME->create(
 			attributes => {
@@ -61,14 +59,11 @@ $im->init_bare;
 			},
 			body => $dot),
 	];
-	my $mime = Email::MIME->create(
+	Email::MIME->create(
 		parts => $parts,
 		header_str => [ From => 'root@z', 'Message-Id' => '<Z@B>',
 			Subject => 'hi']
-	);
-	$mime = $mime->as_string;
-	$mime =~ s/\r\n/\n/g; # normalize to LF only
-	$mime = PublicInbox::MIME->new($mime);
+	)}; # mime_load sub
 	$im->add($mime);
 	$im->done;
 
diff --git a/t/psgi_v2.t b/t/psgi_v2.t
index bc26a112..5d212ca6 100644
--- a/t/psgi_v2.t
+++ b/t/psgi_v2.t
@@ -225,6 +225,7 @@ test_psgi(sub { $www->call(@_) }, sub {
 
 	# ensure conflicted attachments can be resolved
 	foreach my $body (qw(old new)) {
+		$mime = mime_load "t/psgi_v2-$body.eml", sub {
 		my $parts = [
 			Email::MIME->create(
 				attributes => { content_type => 'text/plain' },
@@ -238,12 +239,12 @@ test_psgi(sub { $www->call(@_) }, sub {
 				body => $body
 			)
 		];
-		$mime = Email::MIME->create(
+		Email::MIME->create(
 			parts => $parts,
 			header_str => [ From => 'root@z',
 				'Message-ID' => '<a@dup>',
 				Subject => 'hi']
-		);
+		)}; # mime_load sub
 		ok($im->add($mime), "added attachment $body");
 	}
 	$im->done;
diff --git a/t/search.t b/t/search.t
index 0fd5fdee..0301fd90 100644
--- a/t/search.t
+++ b/t/search.t
@@ -371,6 +371,7 @@ $ibx->with_umask(sub {
 }
 
 $ibx->with_umask(sub {
+	my $amsg = mime_load 't/search-amsg.eml', sub {
 	my $part1 = Email::MIME->create(
                  attributes => {
                      content_type => 'text/plain',
@@ -391,7 +392,7 @@ $ibx->with_umask(sub {
                  },
                  body_str => 'inside another',
 	);
-	my $amsg = Email::MIME->create(
+	Email::MIME->create(
 		header_str => [
 			Subject => 'see attachment',
 			'Message-ID' => '<file@attached>',
@@ -399,7 +400,8 @@ $ibx->with_umask(sub {
 			To => 'list@example.com',
 		],
 		parts => [ $part1, $part2 ],
-	);
+	)}; # mime_load sub
+
 	ok($rw->add_message($amsg), 'added attachment');
 	$rw_commit->();
 	$ro->reopen;

  reply	other threads:[~2020-04-25  5:52 UTC|newest]

Thread overview: 5+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2020-04-25  5:52 [PATCH 0/3] remove Email::MIME->create use Eric Wong
2020-04-25  5:52 ` Eric Wong [this message]
2020-04-25  5:52 ` [PATCH 2/3] tests: remove Email::MIME->create use entirely Eric Wong
2020-04-25  5:52 ` [PATCH 3/3] tests: replace mime_from_path with mime_load Eric Wong
2020-04-26  7:35 ` [PATCH 4/3] testcommon: mime_load: drop extra $cb arg Eric Wong

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

  List information: http://public-inbox.org/README

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=20200425055223.21879-2-e@yhbt.net \
    --to=e@yhbt.net \
    --cc=meta@public-inbox.org \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
Code repositories for project(s) associated with this public inbox

	https://80x24.org/public-inbox.git

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).