blob: 879c5d1af0b984cf93440c8d4d2ce1fd971688a2 (
plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
|
MAILBOX="INBOX"
TIMEOUT=60
N=2048
step_start "\`pullimap --idle\` refuses to create the state file"
! pullimap --idle "remote" || error
step_done
step_start "\`pullimap\` creates statefile with mode 0600"
pullimap "remote" || error
if ! st="$(stat -c"%#a" -- "$XDG_DATA_HOME/pullimap/remote")" || [ "$st" != "0600" ]; then
error "$XDG_DATA_HOME/pullimap/remote has mode $st != 0600"
fi
step_done
# compare mailboxes (can't compare the RFC 3501 TEXT as the LMTPd inconditionally
# adds a Return-Path: header -- and also Delivered-To: and Received: to by default)
list_mails_sha256() {
local u="$1" guid uid
local fields="body date.sent imap.bodystructure imap.envelope"
while read guid uid; do
doveadm -u "$u" -f "flow" fetch "$fields" mailbox-guid "$guid" uid "$uid" | sha256sum
done < <(doveadm -u "$u" search mailbox "$MAILBOX") | sort -f
}
check() {
diff -u --label="local/mails" --label="remote/mails" \
<( list_mails_sha256 "local" ) \
<( list_mails_sha256 "remote" ) \
|| error "mailboxes differ"
}
message_from() {
local date="$(date +"%s.%N")" sender="$1"
cat <<-EOF
From: $sender
To: <me@example.net>
Date: $(date -R -d@"$date")
Message-ID: <$date@example.net>
EOF
xxd -ps -l8 /dev/urandom
}
step_start "Quote envelope sender address"
declare -a senders=("sender" "first.last" "foo-bar" \"\" "\"x\\\" #&\\\\y\"")
for s in "${senders[@]}"; do
message_from "$s@example.net" | deliver -u "remote" -- -m "$MAILBOX"
done
pullimap "remote" || error
check
for s in "${senders[@]}"; do
grep -F " from <$s@example.net> " <"$STDERR" || error "$s"
done
step_done
step_start "Mail without data"
deliver -u "remote" -- -m "$MAILBOX" </dev/null
pullimap "remote" || error
check
step_done
step_start "Dot-leading lines"
deliver -u "remote" -- -m "$MAILBOX" <<-EOF
From: alice@example.net
To: bob@example.net
Date: $(date -R)
Message-ID: <$(xxd -ps -l8 /dev/urandom)@example.net>
foo
.
.bar
..baz
EOF
# we can't add a test for message data not ending with CRLF, because the
# LMTP/SMTP client needs to add a CRLF so local and remote message
# bodies would differ. that said, while such a message could be added
# by IMAP and LDA, it's not valid for SMTP (RFC 5321 sec. 4.1.1.4)
pullimap "remote" || error
check
step_done
# make sure remote UIDs are 11-bytes long
doveadm -u "remote" mailbox update --min-next-uid 1000000000 "$MAILBOX"
# Add some messages and sync
step_start "Fetching messages"
for ((i = 0; i < 32; i++)); do
sample_message | deliver -u "remote" -- -m "$MAILBOX"
done
pullimap "remote" || error
check
# same thing, but with some missing messages
for ((i = 0; i < N; i+=2)); do
sample_message | deliver -u "remote" -- -m "$MAILBOX"
deliver -u "remote" -- -m "$MAILBOX" </dev/null # odd seqnum
done
for ((i = 0; i < N; i+=2)); do
# expunge every other message
doveadm -u "remote" expunge mailbox "$MAILBOX" $((N-i+32+7))
sample_message | deliver -u "remote" -- -m "$MAILBOX"
done
pullimap "remote" || error
check
# count unseen remote messages
doveadm -u "remote" search mailbox "$MAILBOX" unseen >"$TMPDIR/unseen"
[ ! -s "$TMPDIR/unseen" ] || error "\\Unseen messages left"
step_done
if [ $TIMEOUT -gt 0 ]; then
step_start "--idle (${TIMEOUT}s)"
pullimap --idle "remote" & PID=$!
trap "ptree_abort $PID" EXIT INT TERM
timer=$(( $(date +%s) + TIMEOUT ))
while [ $(date +%s) -le $timer ]; do
n="$(shuf -n1 -i1-5)"
for (( i=0; i < n; i++)); do
sample_message | deliver -u "remote" -- -m "$MAILBOX"
done
s=$(shuf -n1 -i1-1500)
[ $s -ge 1000 ] && s="$(printf "1.%03d" $((s-1000)))" || s="$(printf "0.%03d" $s)"
sleep "$s"
done
sleep 5
ptree_abort $PID
trap - EXIT INT TERM
check
step_done
fi
step_start "Purging"
echo "purge-after = 0" >>"$XDG_CONFIG_HOME/pullimap/config"
for ((i = 0; i < 32; i++)); do
sample_message | deliver -u "remote" -- -m "$MAILBOX"
done
pullimap "remote"
doveadm -u "remote" search mailbox "$MAILBOX" all >"$TMPDIR/messages"
[ ! -s "$TMPDIR/messages" ] || error "messages left"
step_done
# vim: set filetype=bash :
|