about summary refs log tree commit homepage
path: root/t
diff options
context:
space:
mode:
authorEric Wong <e@yhbt.net>2020-06-10 07:04:40 +0000
committerEric Wong <e@yhbt.net>2020-06-13 07:55:45 +0000
commitcfae078171fc1453be0795e4ba5f0252627ebba3 (patch)
tree743f0b1b5cf356bf018b5619619edd362dcdd0a8 /t
parent48180dbb004b5f59b2e80613b6fa2e5e869316f1 (diff)
downloadpublic-inbox-cfae078171fc1453be0795e4ba5f0252627ebba3.tar.gz
Finish up the IMAP-only portion of iterative config reloading,
which allows us to create all sub-ranges of an inbox up front.
The InboxIdler still uses ->each_inbox which will struggle with
100K inboxes.

Having messages in the top-level newsgroup name of an inbox will
still waste bandwidth for clients which want to do full syncs
once there's a rollover to a new 50K range.  So instead, make
every inbox accessible exclusively via 50K slices in the form of
"$NEWSGROUP.$UID_MIN-$UID_END".

This introduces the DummyInbox, which makes $NEWSGROUP
and every parent component a selectable, empty inbox.
This aids navigation with mutt and possibly other MUAs.

Finally, the xt/perf-imap-list maintainer test is broken, now,
so remove it.  The grep perlfunc is already proven effective,
and we'll have separate tests for mocking out ~100k inboxes.
Diffstat (limited to 't')
-rw-r--r--t/imap.t33
-rw-r--r--t/imapd.t22
2 files changed, 42 insertions, 13 deletions
diff --git a/t/imap.t b/t/imap.t
index aa262a19..af59ef69 100644
--- a/t/imap.t
+++ b/t/imap.t
@@ -6,16 +6,39 @@ use strict;
 use Test::More;
 use PublicInbox::IMAP;
 use PublicInbox::IMAPD;
+use PublicInbox::TestCommon;
+require_mods(qw(DBD::SQLite));
+require_git 2.6;
 
-{ # make sure we get '%' globbing right
+my ($tmpdir, $for_destroy) = tmpdir();
+my $cfgfile = "$tmpdir/config";
+{
+        open my $fh, '>', $cfgfile or BAIL_OUT $!;
+        print $fh <<EOF or BAIL_OUT $!;
+[publicinbox "a"]
+        inboxdir = $tmpdir/a
+        newsgroup = x.y.z
+[publicinbox "b"]
+        inboxdir = $tmpdir/b
+        newsgroup = x.z.y
+[publicinbox "c"]
+        inboxdir = $tmpdir/c
+        newsgroup = IGNORE.THIS
+EOF
+        close $fh or BAIL_OUT $!;
+        local $ENV{PI_CONFIG} = $cfgfile;
+        for my $x (qw(a b c)) {
+                ok(run_script(['-init', '-Lbasic', '-V2', $x, "$tmpdir/$x",
+                                "https://example.com/$x", "$x\@example.com"]),
+                        "init $x");
+        }
+        my $imapd = PublicInbox::IMAPD->new;
         my @w;
         local $SIG{__WARN__} = sub { push @w, @_ };
-        my @n = map { { newsgroup => $_ } } (qw(x.y.z x.z.y IGNORE.THIS));
-        my $self = { imapd => { grouplist => \@n } };
-        PublicInbox::IMAPD::refresh_inboxlist($self->{imapd});
+        $imapd->refresh_groups;
+        my $self = { imapd => $imapd };
         is(scalar(@w), 1, 'got a warning for upper-case');
         like($w[0], qr/IGNORE\.THIS/, 'warned about upper-case');
-
         my $res = PublicInbox::IMAP::cmd_list($self, 'tag', 'x', '%');
         is(scalar($$res =~ tr/\n/\n/), 2, 'only one result');
         like($$res, qr/ x\r\ntag OK/, 'saw expected');
diff --git a/t/imapd.t b/t/imapd.t
index a5324f78..017bfa0b 100644
--- a/t/imapd.t
+++ b/t/imapd.t
@@ -16,6 +16,9 @@ if ($can_compress) { # hope this gets fixed upstream, soon
         $imap_client = 'PublicInbox::IMAPClient';
 }
 
+require_ok 'PublicInbox::IMAP';
+my $first_range = '1-'.PublicInbox::IMAP::UID_BLOCK();
+
 my $level = '-Lbasic';
 SKIP: {
         require_mods('Search::Xapian', 1);
@@ -87,11 +90,13 @@ ok(!$mic->examine('foo') && ($e = $@), 'EXAMINE non-existent');
 like($e, qr/\bNO\b/, 'got a NO on EXAMINE for non-existent');
 ok(!$mic->select('foo') && ($e = $@), 'EXAMINE non-existent');
 like($e, qr/\bNO\b/, 'got a NO on EXAMINE for non-existent');
-ok($mic->select('inbox.i1'), 'SELECT succeeds');
-ok($mic->examine('INBOX.i1'), 'EXAMINE succeeds');
-my @raw = $mic->status('inbox.i1', qw(Messages uidnext uidvalidity));
+my $mailbox1 = "inbox.i1.$first_range";
+ok($mic->select('inbox.i1'), 'SELECT on parent succeeds');
+ok($mic->select($mailbox1), 'SELECT succeeds');
+ok($mic->examine($mailbox1), 'EXAMINE succeeds');
+my @raw = $mic->status($mailbox1, qw(Messages uidnext uidvalidity));
 is(scalar(@raw), 2, 'got status response');
-like($raw[0], qr/\A\*\x20STATUS\x20inbox\.i1\x20
+like($raw[0], qr/\A\*\x20STATUS\x20inbox\.i1\.$first_range\x20
         \(MESSAGES\x20\d+\x20UIDNEXT\x20\d+\x20UIDVALIDITY\x20\d+\)\r\n/sx);
 like($raw[1], qr/\A\S+ OK /, 'finished status response');
 
@@ -99,7 +104,7 @@ like($raw[1], qr/\A\S+ OK /, 'finished status response');
 like($raw[0], qr/^\* LIST \(.*?\) "\." inbox/,
         'got an inbox');
 like($raw[-1], qr/^\S+ OK /, 'response ended with OK');
-is(scalar(@raw), scalar(@V) + 2, 'default LIST response');
+is(scalar(@raw), scalar(@V) + 4, 'default LIST response');
 @raw = $mic->list('', 'inbox.i1');
 is(scalar(@raw), 2, 'limited LIST response');
 like($raw[0], qr/^\* LIST \(.*?\) "\." inbox/,
@@ -199,7 +204,7 @@ SKIP: {
         skip 'Mail::IMAPClient too old for ->compress', 2 if !$can_compress;
         my $c = $imap_client->new(%mic_opt);
         ok($c && $c->compress, 'compress enabled');
-        ok($c->examine('inbox.i1'), 'EXAMINE succeeds after COMPRESS');
+        ok($c->examine($mailbox1), 'EXAMINE succeeds after COMPRESS');
         $ret = $c->search('uid 1:*') or BAIL_OUT "SEARCH FAIL $@";
         is_deeply($ret, [ 1 ], 'search UID 1:* works after compression');
 }
@@ -216,11 +221,12 @@ $pi_config->each_inbox(sub {
         my $ng = $ibx->{newsgroup};
         my $mic = $imap_client->new(%mic_opt);
         ok($mic && $mic->login && $mic->IsAuthenticated, "authed $name");
-        my $uidnext = $mic->uidnext($ng); # we'll fetch BODYSTRUCTURE on this
+        my $mb = "$ng.$first_range";
+        my $uidnext = $mic->uidnext($mb); # we'll fetch BODYSTRUCTURE on this
         ok($uidnext, 'got uidnext for later fetch');
         is_deeply([$mic->has_capability('IDLE')], ['IDLE'], "IDLE capa $name");
         ok(!$mic->idle, "IDLE fails w/o SELECT/EXAMINE $name");
-        ok($mic->examine($ng), "EXAMINE $ng succeeds");
+        ok($mic->examine($mb), "EXAMINE $ng succeeds");
         ok(my $idle_tag = $mic->idle, "IDLE succeeds on $ng");
 
         open(my $fh, '<', 't/data/message_embed.eml') or BAIL_OUT("open: $!");