aboutsummaryrefslogtreecommitdiffstats
path: root/tests
diff options
context:
space:
mode:
authorGuilhem Moulin <guilhem@fripost.org>2019-11-11 00:39:09 +0100
committerGuilhem Moulin <guilhem@fripost.org>2019-11-13 06:23:57 +0100
commit0a2558aabfefd6800fe74c24e5aff2b0d47cc5e2 (patch)
treec8887efc8526b25683924a90b757655cd3fb1772 /tests
parentccf90182d04c064bd9327c5e7067ed4b9dc32f41 (diff)
Avoid sending large UID EXPUNGE|FETCH|STORE and APPEND commands.
UID EXPUNGE|FETCH|STORE commands are now split into multiple (sequential) commands when their set representation exceeds 4096 bytes in size. Without splitting logic set representations could grow arbitrarily large, and exceed the server's maximum command size. This adds roundtrips which could be eliminated by pipelining, but it's unlikely to make any difference in typical synchronization work. While set representations seem to remain small in practice, they might grow significantly if many non-contiguous UIDs were flagged and/or expunged, and later synchronized at once. Furthermore, for MULTIAPPEND-capable servers, the number of messages is limited to 128 per APPEND command (also subject to a combined literal size of 1MiB like before). These numbers are currently not configurable. They're intentionally lower than Dovecot's default maximum command size (64k) in order to avoid a deadlock situation after sending 8k-long commands under COMPRESS=DEFLATE: https://dovecot.org/pipermail/dovecot/2019-November/117522.html .
Diffstat (limited to 'tests')
-rw-r--r--tests/list1
-rw-r--r--tests/snippets/dovecot/imapd.conf3
l---------tests/split-set/interimap.remote1
l---------tests/split-set/remote.conf1
-rw-r--r--tests/split-set/t43
5 files changed, 49 insertions, 0 deletions
diff --git a/tests/list b/tests/list
index 8bb4478..a18cb29 100644
--- a/tests/list
+++ b/tests/list
@@ -40,6 +40,7 @@ repair --repair
compress COMPRESS=DEFLATE
condstore CONDSTORE
+split-set Split large sets to avoid extra-long command lines
. SSL/TLS
starttls-logindisabled LOGINDISABLED STARTTLS
diff --git a/tests/snippets/dovecot/imapd.conf b/tests/snippets/dovecot/imapd.conf
index 18c60f8..2b26451 100644
--- a/tests/snippets/dovecot/imapd.conf
+++ b/tests/snippets/dovecot/imapd.conf
@@ -14,3 +14,6 @@ service imap-login {
ssl = yes
}
}
+
+# we should avoid sending command lines that are too long
+imap_max_line_length = 8192
diff --git a/tests/split-set/interimap.remote b/tests/split-set/interimap.remote
new file mode 120000
index 0000000..a4ea3f3
--- /dev/null
+++ b/tests/split-set/interimap.remote
@@ -0,0 +1 @@
+../auth-sasl-plain/interimap.remote \ No newline at end of file
diff --git a/tests/split-set/remote.conf b/tests/split-set/remote.conf
new file mode 120000
index 0000000..dbbb908
--- /dev/null
+++ b/tests/split-set/remote.conf
@@ -0,0 +1 @@
+../auth-sasl-plain/remote.conf \ No newline at end of file
diff --git a/tests/split-set/t b/tests/split-set/t
new file mode 100644
index 0000000..5e8ea52
--- /dev/null
+++ b/tests/split-set/t
@@ -0,0 +1,43 @@
+N=2048
+
+# XXX with COMPRESS=DEFLATE dovecot-imapd 2.3.4 hangs when the command
+# line exceeds 'imap_max_line_length' (or 8192, whichever is smaller)
+# bytes, instead of returning a tagged BAD response.
+# https://dovecot.org/pipermail/dovecot/2019-November/117522.html
+
+# set UIDNEXT to 10^9 so all uids are 10 chars long, otherwise we'd need
+# to add many more messages to obtain large sets
+doveadm -u "local" mailbox update --min-next-uid 1000000000 "INBOX"
+doveadm -u "remote" mailbox update --min-next-uid 1000000000 "INBOX"
+
+for ((i = 0; i < N; i++)); do
+ u="$(shuf -n1 -e "local" "remote")"
+ sample_message | deliver -u "$u"
+done
+
+interimap_init
+check_mailbox_status "INBOX"
+
+# mark every other message as \Seen on the local server
+for ((i = 0; i < N; i+=2)); do
+ doveadm -u "local" flags add "\\Seen" mailbox "INBOX" $((N-i))
+done
+
+# send the changes to the remote; this results into an UID STORE set
+# representation of size 11*N/2-1, which exceeds $imap_max_line_length
+interimap
+check_mailbox_status "INBOX"
+
+# now expunge every other message on the remote server; this results
+# into large UID STORE and UID EXPUNGE set representation
+for ((i = 0; i < N; i+=2)); do
+ doveadm -u "local" expunge mailbox "INBOX" $((N-i))
+ # add some more messages
+ u="$(shuf -n1 -e "local" "remote")"
+ sample_message | deliver -u "$u"
+done
+
+interimap || error
+check_mailbox_status "INBOX"
+
+# vim: set filetype=sh :