]> Sergey Matveev's repositories - public-inbox.git/blob - xt/cmp-msgview.t
9b06f88deade239f5257de99b96bf4eec2ed98dc
[public-inbox.git] / xt / cmp-msgview.t
1 #!perl -w
2 # Copyright (C) 2020-2021 all contributors <meta@public-inbox.org>
3 # License: AGPL-3.0+ <https://www.gnu.org/licenses/agpl-3.0.txt>
4 use strict;
5 use Test::More;
6 use Benchmark qw(:all);
7 use PublicInbox::Inbox;
8 use PublicInbox::View;
9 use PublicInbox::TestCommon;
10 use PublicInbox::Eml;
11 use Digest::MD5;
12 require_git(2.19);
13 require_mods qw(Data::Dumper Email::MIME Plack::Util);
14 Data::Dumper->import('Dumper');
15 require PublicInbox::MIME;
16 my ($tmpdir, $for_destroy) = tmpdir();
17 my $inboxdir = $ENV{GIANT_INBOX_DIR};
18 plan skip_all => "GIANT_INBOX_DIR not defined for $0" unless $inboxdir;
19 my @cat = qw(cat-file --buffer --batch-check --batch-all-objects --unordered);
20 my $ibx = PublicInbox::Inbox->new({ inboxdir => $inboxdir, name => 'perf' });
21 my $git = $ibx->git;
22 my $fh = $git->popen(@cat);
23 vec(my $vec = '', fileno($fh), 1) = 1;
24 select($vec, undef, undef, 60) or die "timed out waiting for --batch-check";
25 my $mime_ctx = {
26         env => { HTTP_HOST => 'example.com', 'psgi.url_scheme' => 'https' },
27         ibx => $ibx,
28         www => Plack::Util::inline_object(style => sub {''}),
29         obuf => \(my $mime_buf = ''),
30         mhref => '../',
31 };
32 my $eml_ctx = { %$mime_ctx, obuf => \(my $eml_buf = '') };
33 my $n = 0;
34 my $m = 0;
35 my $ndiff_html = 0;
36 my $dig_cls = 'Digest::MD5';
37 my $digest_attach = sub { # ensure ->body (not ->body_raw) matches
38         my ($p, $cmp_arg) = @_;
39         my $part = shift @$p;
40         my $dig = $cmp_arg->[0] //= $dig_cls->new;
41         $dig->add($part->body_raw);
42         push @$cmp_arg, join(', ', @$p);
43 };
44
45 my $git_cb = sub {
46         my ($bref, $oid) = @_;
47         local $SIG{__WARN__} = sub { diag "$inboxdir $oid ", @_ };
48         ++$m;
49         my $mime = PublicInbox::MIME->new($$bref);
50         PublicInbox::View::multipart_text_as_html($mime, $mime_ctx);
51         my $eml = PublicInbox::Eml->new($$bref);
52         PublicInbox::View::multipart_text_as_html($eml, $eml_ctx);
53         if ($eml_buf ne $mime_buf) {
54                 ++$ndiff_html;
55                 open my $fh, '>', "$tmpdir/mime" or die $!;
56                 print $fh $mime_buf or die $!;
57                 close $fh or die $!;
58                 open $fh, '>', "$tmpdir/eml" or die $!;
59                 print $fh $eml_buf or die $!;
60                 close $fh or die $!;
61                 # using `git diff', diff(1) may not be installed
62                 diag "$inboxdir $oid differs";
63                 diag xqx([qw(git diff), "$tmpdir/mime", "$tmpdir/eml"]);
64         }
65         $eml_buf = $mime_buf = '';
66
67         # don't tolerate differences in attachment downloads
68         $mime = PublicInbox::MIME->new($$bref);
69         $mime->each_part($digest_attach, my $mime_cmp = [], 1);
70         $eml = PublicInbox::Eml->new($$bref);
71         $eml->each_part($digest_attach, my $eml_cmp = [], 1);
72         $mime_cmp->[0] = $mime_cmp->[0]->hexdigest;
73         $eml_cmp->[0] = $eml_cmp->[0]->hexdigest;
74         # don't have millions of "ok" lines
75         if (join("\0", @$eml_cmp) ne join("\0", @$mime_cmp)) {
76                 diag Dumper([ $oid, eml => $eml_cmp, mime =>$mime_cmp ]);
77                 is_deeply($eml_cmp, $mime_cmp, "$inboxdir $oid match");
78         }
79 };
80 my $t = timeit(1, sub {
81         while (<$fh>) {
82                 my ($oid, $type) = split / /;
83                 next if $type ne 'blob';
84                 ++$n;
85                 $git->cat_async($oid, $git_cb);
86         }
87         $git->async_wait_all;
88 });
89 is($m, $n, 'rendered all messages');
90
91 # we'll tolerate minor differences in HTML rendering
92 diag "$ndiff_html HTML differences";
93
94 done_testing();