lei/store: stop shard workers + cat-file on idle
[public-inbox.git] / t / watch_mh.t
blob047937504bba393437ec842fbf8914e1641f6bad
1 #!perl -w
2 # Copyright (C) all contributors <meta@public-inbox.org>
3 # License: AGPL-3.0+ <https://www.gnu.org/licenses/agpl-3.0.txt>
4 use v5.12;
5 use PublicInbox::Eml;
6 use PublicInbox::TestCommon;
7 use PublicInbox::Import;
8 use PublicInbox::IO qw(write_file);
9 use POSIX qw(mkfifo);
10 use File::Copy qw(cp);
11 use autodie qw(rename mkdir);
13 my $tmpdir = tmpdir;
14 my $git_dir = "$tmpdir/test.git";
15 my $mh = "$tmpdir/mh";
16 my $spamdir = "$tmpdir/mh-spam";
17 mkdir $_ for ($mh, $spamdir);
18 use_ok 'PublicInbox::Watch';
19 my $addr = 'test-public@example.com';
20 my $default_branch = PublicInbox::Import::default_branch;
21 PublicInbox::Import::init_bare($git_dir);
22 my $msg = <<EOF;
23 From: user\@example.com
24 To: $addr
25 Subject: spam
26 Message-ID: <a\@b.com>
27 Date: Sat, 18 Jun 2016 00:00:00 +0000
29 something
30 EOF
32 cp 't/plack-qp.eml', "$mh/1";
33 mkfifo("$mh/5", 0777) or xbail "mkfifo: $!"; # FIFO to ensure no stuckage
34 my $cfg = cfg_new $tmpdir, <<EOF;
35 [publicinbox "test"]
36         address = $addr
37         inboxdir = $git_dir
38         watch = mh:$mh
39 [publicinboxlearn]
40         watchspam = mh:$spamdir
41 EOF
42 PublicInbox::Watch->new($cfg)->scan('full');
43 my $git = PublicInbox::Git->new($git_dir);
45         my @list = $git->qx('rev-list', $default_branch);
46         is(scalar @list, 1, 'one revision in rev-list');
47         $git->cleanup;
50 # end-to-end test which actually uses inotify/kevent
52         my $env = { PI_CONFIG => $cfg->{-f} };
53         # n.b. --no-scan is only intended for testing atm
54         my $wm = start_script([qw(-watch --no-scan)], $env);
55         no_pollerfd($wm->{pid});
57         my $eml = eml_load 't/data/binary.patch';
58         $eml->header_set('Cc', $addr);
59         write_file '>', "$mh/2.tmp", $eml->as_string;
61         use_ok 'PublicInbox::InboxIdle';
62         use_ok 'PublicInbox::DS';
63         my $delivered = 0;
64         my $cb = sub {
65                 my ($ibx) = @_;
66                 diag "message delivered to `$ibx->{name}'";
67                 $delivered++;
68         };
69         PublicInbox::DS->Reset;
70         my $ii = PublicInbox::InboxIdle->new($cfg);
71         my $obj = bless \$cb, 'PublicInbox::TestCommon::InboxWakeup';
72         $cfg->each_inbox(sub { $_[0]->subscribe_unlock('ident', $obj) });
73         local @PublicInbox::DS::post_loop_do = (sub { $delivered == 0 });
75         # wait for -watch to setup inotify watches
76         my $sleep = 1;
77         if (eval { require PublicInbox::Inotify } && -d "/proc/$wm->{pid}/fd") {
78                 my $end = time + 2;
79                 my (@ino, @ino_info);
80                 do {
81                         @ino = grep {
82                                 (readlink($_)//'') =~ /\binotify\b/
83                         } glob("/proc/$wm->{pid}/fd/*");
84                 } until (@ino || time > $end || !tick);
85                 if (scalar(@ino) == 1) {
86                         my $ino_fd = (split(m'/', $ino[0]))[-1];
87                         my $ino_fdinfo = "/proc/$wm->{pid}/fdinfo/$ino_fd";
88                         while (time < $end && open(my $fh, '<', $ino_fdinfo)) {
89                                 @ino_info = grep(/^inotify wd:/, <$fh>);
90                                 last if @ino_info >= 2;
91                                 tick;
92                         }
93                         $sleep = undef if @ino_info >= 2;
94                 }
95         }
96         if ($sleep) {
97                 diag "waiting ${sleep}s for -watch to start up";
98                 sleep $sleep;
99         }
100         rename "$mh/2.tmp", "$mh/2";
101         diag 'waiting for -watch to import new message';
102         PublicInbox::DS::event_loop();
104         my $subj = $eml->header_raw('Subject');
105         my $head = $git->qx(qw(cat-file commit HEAD));
106         like $head, qr/^\Q$subj\E/sm, 'new commit made';
108         $wm->kill;
109         $wm->join;
110         $ii->close;
111         PublicInbox::DS->Reset;
114 my $is_mh = sub { PublicInbox::Watch::is_mh(my $val = shift) };
116 is $is_mh->('mh:/hello//world'), '/hello/world', 'extra slash gone';
117 is $is_mh->('MH:/hello/world/'), '/hello/world', 'trailing slash gone';
118 is $is_mh->('maildir:/hello/world/'), undef, 'non-MH rejected';
120 done_testing;