-
Notifications
You must be signed in to change notification settings - Fork 145
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Merge pull request #4977 from rsto/xapian_add_messageid
Index Message-ID, References and In-Reply-To headers in Xapian
- Loading branch information
Showing
22 changed files
with
938 additions
and
409 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,124 @@ | ||
#!perl | ||
use Cassandane::Tiny; | ||
|
||
sub test_email_query_messageid | ||
: needs_component_jmap : JMAPExtensions : needs_component_sieve { | ||
my ($self) = @_; | ||
my $jmap = $self->{jmap}; | ||
my $imap = $self->{store}->get_client(); | ||
|
||
$jmap->AddUsing('https://cyrusimap.org/ns/jmap/debug'); | ||
$jmap->AddUsing('https://cyrusimap.org/ns/jmap/performance'); | ||
|
||
my $mime = <<'EOF'; | ||
From: from@local | ||
To: to@local | ||
Message-ID: <[email protected]> | ||
Subject: test | ||
Date: Mon, 13 Apr 2020 15:34:03 +0200 | ||
MIME-Version: 1.0 | ||
Content-Type: text/plain | ||
test | ||
EOF | ||
$mime =~ s/\r?\n/\r\n/gs; | ||
$imap->append('INBOX', $mime) || die $@; | ||
|
||
xlog $self, "run squatter"; | ||
$self->{instance}->run_command({ cyrus => 1 }, 'squatter'); | ||
|
||
xlog $self, "Assert 'messageId' filter condition"; | ||
|
||
my $res = $jmap->CallMethods([ | ||
[ 'Email/query', {}, 'R1' ], | ||
]); | ||
my $emailId = $res->[0][1]{ids}[0]; | ||
$self->assert_not_null($emailId); | ||
|
||
my $res = $jmap->CallMethods([ | ||
[ | ||
'Email/query', | ||
{ | ||
filter => { | ||
messageId => '[email protected]', | ||
}, | ||
}, | ||
'R1' | ||
], | ||
[ | ||
'Email/query', | ||
{ | ||
filter => { | ||
header => [ 'message-id', '[email protected]' ], | ||
}, | ||
}, | ||
'R2' | ||
], | ||
]); | ||
$self->assert_deep_equals([$emailId], $res->[0][1]{ids}); | ||
$self->assert_deep_equals(['xapian'], $res->[0][1]{performance}{details}{filters}); | ||
$self->assert_equals(JSON::true, $res->[0][1]{performance}{details}{isGuidSearch}); | ||
$self->assert_deep_equals([$emailId], $res->[1][1]{ids}); | ||
$self->assert_deep_equals(['cache'], $res->[1][1]{performance}{details}{filters}); | ||
$self->assert_equals(JSON::false, $res->[1][1]{performance}{details}{isGuidSearch}); | ||
|
||
xlog $self, "Assert 'messageId' filter in Sieve"; | ||
|
||
$imap->create("matches") or die; | ||
$self->{instance}->install_sieve_script( | ||
<<'EOF' | ||
require ["x-cyrus-jmapquery", "x-cyrus-log", "variables", "fileinto"]; | ||
if | ||
allof( not string :is "${stop}" "Y", | ||
jmapquery text: | ||
{ | ||
"messageId" : "[email protected]" | ||
} | ||
. | ||
) | ||
{ | ||
fileinto "matches"; | ||
} | ||
EOF | ||
); | ||
|
||
$mime = <<'EOF'; | ||
From: from2@local | ||
To: to2@local | ||
Message-ID: <[email protected]> | ||
Subject: test2 | ||
Date: Mon, 13 Apr 2020 15:34:03 +0200 | ||
MIME-Version: 1.0 | ||
Content-Type: text/plain | ||
test | ||
EOF | ||
$mime =~ s/\r?\n/\r\n/gs; | ||
my $msg = Cassandane::Message->new(); | ||
$msg->set_lines(split /\n/, $mime); | ||
$self->{instance}->deliver($msg); | ||
$self->assert_num_equals(1, $imap->message_count('matches')); | ||
|
||
xlog $self, "Assert 'messageId' filter on legacy index version falls back to cache"; | ||
|
||
my $xapdirs = ($self->{instance}->run_mbpath(-u => 'cassandane'))->{xapian}; | ||
my $xdbpath = $xapdirs->{t1} . "/xapian"; | ||
$self->{instance}->run_command( | ||
{}, | ||
'xapian-metadata', 'set', $xdbpath, 'cyrus.db_version', '16,17' | ||
); | ||
$res = $jmap->CallMethods([ | ||
[ | ||
'Email/query', | ||
{ | ||
filter => { | ||
messageId => '[email protected]', | ||
}, | ||
}, | ||
'R1' | ||
], | ||
]); | ||
$self->assert_deep_equals([$emailId], $res->[0][1]{ids}); | ||
$self->assert_deep_equals(['cache'], $res->[0][1]{performance}{details}{filters}); | ||
$self->assert_equals(JSON::false, $res->[0][1]{performance}{details}{isGuidSearch}); | ||
} |
177 changes: 177 additions & 0 deletions
177
cassandane/tiny-tests/JMAPEmail/email_query_references_inreplyto
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,177 @@ | ||
#!perl | ||
use Cassandane::Tiny; | ||
|
||
sub test_email_query_references_inreplyto | ||
: needs_component_jmap : JMAPExtensions : needs_component_sieve { | ||
my ($self) = @_; | ||
my $jmap = $self->{jmap}; | ||
my $imap = $self->{store}->get_client(); | ||
|
||
$jmap->AddUsing('https://cyrusimap.org/ns/jmap/debug'); | ||
$jmap->AddUsing('https://cyrusimap.org/ns/jmap/performance'); | ||
|
||
xlog $self, "Assert 'inReplyTo' and 'references' filter conditions"; | ||
|
||
my $res = $jmap->CallMethods([ [ | ||
'Email/set', | ||
{ | ||
create => { | ||
email1 => { | ||
'header:references' => '<refA@local> <refB@local>', | ||
mailboxIds => { '$inbox' => JSON::true }, | ||
from => [ { email => 'foo@local' } ], | ||
to => [ { email => 'bar@local' } ], | ||
subject => 'test1', | ||
bodyStructure => { | ||
type => 'text/plain', | ||
partId => 'part1', | ||
}, | ||
bodyValues => { | ||
part1 => { | ||
value => 'test', | ||
} | ||
} | ||
}, | ||
email2 => { | ||
'header:in-reply-to' => '<replytoA@local>', | ||
mailboxIds => { '$inbox' => JSON::true }, | ||
from => [ { email => 'foo@local' } ], | ||
to => [ { email => 'bar@local' } ], | ||
subject => 'test2', | ||
bodyStructure => { | ||
type => 'text/plain', | ||
partId => 'part1', | ||
}, | ||
bodyValues => { | ||
part1 => { | ||
value => 'test', | ||
} | ||
} | ||
} | ||
} | ||
}, | ||
'createEmail' | ||
] ]); | ||
my $email1Id = $res->[0][1]{created}{email1}{id}; | ||
$self->assert_not_null($email1Id); | ||
my $email2Id = $res->[0][1]{created}{email2}{id}; | ||
$self->assert_not_null($email2Id); | ||
|
||
xlog $self, "run squatter"; | ||
$self->{instance}->run_command({ cyrus => 1 }, 'squatter'); | ||
|
||
my $res = $jmap->CallMethods([ | ||
[ | ||
'Email/query', | ||
{ | ||
filter => { | ||
references => 'refA@local', | ||
}, | ||
}, | ||
'R1' | ||
], | ||
[ | ||
'Email/query', | ||
{ | ||
filter => { | ||
header => [ 'references', 'refA@local' ], | ||
}, | ||
}, | ||
'R2' | ||
], | ||
[ | ||
'Email/query', | ||
{ | ||
filter => { | ||
references => 'refB@local', | ||
}, | ||
}, | ||
'R3' | ||
], | ||
[ | ||
'Email/query', | ||
{ | ||
filter => { | ||
inReplyTo => 'replytoA@local', | ||
}, | ||
}, | ||
'R4' | ||
], | ||
]); | ||
$self->assert_deep_equals([$email1Id], $res->[0][1]{ids}); | ||
$self->assert_deep_equals(['xapian'], $res->[0][1]{performance}{details}{filters}); | ||
$self->assert_equals(JSON::true, $res->[0][1]{performance}{details}{isGuidSearch}); | ||
|
||
$self->assert_deep_equals([$email1Id], $res->[1][1]{ids}); | ||
$self->assert_deep_equals(['cache'], $res->[1][1]{performance}{details}{filters}); | ||
$self->assert_equals(JSON::false, $res->[1][1]{performance}{details}{isGuidSearch}); | ||
|
||
$self->assert_deep_equals([$email1Id], $res->[2][1]{ids}); | ||
$self->assert_deep_equals(['xapian'], $res->[2][1]{performance}{details}{filters}); | ||
$self->assert_equals(JSON::true, $res->[2][1]{performance}{details}{isGuidSearch}); | ||
|
||
$self->assert_deep_equals([$email2Id], $res->[3][1]{ids}); | ||
$self->assert_deep_equals(['xapian'], $res->[3][1]{performance}{details}{filters}); | ||
$self->assert_equals(JSON::true, $res->[3][1]{performance}{details}{isGuidSearch}); | ||
|
||
xlog $self, "Assert 'inReplyTo' and 'references' filters in Sieve"; | ||
|
||
$imap->create("matches") or die; | ||
$self->{instance}->install_sieve_script( | ||
<<'EOF' | ||
require ["x-cyrus-jmapquery", "x-cyrus-log", "variables", "fileinto"]; | ||
if | ||
allof( not string :is "${stop}" "Y", | ||
jmapquery text: | ||
{ | ||
"operator" : "OR", | ||
"conditions": [{ | ||
"references": "refC@local" | ||
}, { | ||
"inReplyTo": "replyToC@local" | ||
}] | ||
} | ||
. | ||
) | ||
{ | ||
fileinto "matches"; | ||
} | ||
EOF | ||
); | ||
|
||
$mime = <<'EOF'; | ||
From: foo@local | ||
To: bar@local | ||
Message-Id: <[email protected]> | ||
References: <refC@local> | ||
Subject: sievetest1 | ||
Date: Mon, 13 Apr 2020 15:34:03 +0200 | ||
MIME-Version: 1.0 | ||
Content-Type: text/plain | ||
test | ||
EOF | ||
$mime =~ s/\r?\n/\r\n/gs; | ||
my $msg = Cassandane::Message->new(); | ||
$msg->set_lines(split /\n/, $mime); | ||
$self->{instance}->deliver($msg); | ||
$self->assert_num_equals(1, $imap->message_count('matches')); | ||
|
||
$mime = <<'EOF'; | ||
From: foo@local | ||
To: bar@local | ||
Message-Id: <[email protected]> | ||
In-Reply-To: <replyToC@local> | ||
Subject: sievetest2 | ||
Date: Mon, 13 Apr 2020 15:34:03 +0200 | ||
MIME-Version: 1.0 | ||
Content-Type: text/plain | ||
test | ||
EOF | ||
$mime =~ s/\r?\n/\r\n/gs; | ||
$msg = Cassandane::Message->new(); | ||
$msg->set_lines(split /\n/, $mime); | ||
$self->{instance}->deliver($msg); | ||
$self->assert_num_equals(2, $imap->message_count('matches')); | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,19 @@ | ||
Description: | ||
|
||
Adds JMAP Email/query filter conditions `messageId`, `references` and `inReplyTo`. | ||
|
||
Config changes: | ||
|
||
None. | ||
|
||
|
||
Upgrade instructions: | ||
|
||
It is recommended to rebuild the Xapian index to make use of these filter | ||
conditions. Otherwise, email queries having these filter fall back to | ||
reading the MIME headers from disk, resulting in slower search. | ||
|
||
|
||
GitHub issue: | ||
|
||
None. |
Oops, something went wrong.