notmuch-test: Eliminate sleeps to speed up test suite run
[notmuch] / test / notmuch-test
1 #!/bin/bash
2 set -e
3
4 find_notmuch_binary ()
5 {
6     dir=$1
7
8     while [ -n "$dir" ]; do
9         bin=$dir/notmuch
10         if [ -x $bin ]; then
11             echo $bin
12             return
13         fi
14         dir=$(dirname $dir)
15         if [ "$dir" = "/" ]; then
16             break
17         fi
18     done
19
20     echo notmuch
21 }
22
23 increment_mtime_amount=0
24 increment_mtime ()
25 {
26     dir=$1
27
28     increment_mtime_amount=$((increment_mtime_amount + 1))
29     touch -d "+${increment_mtime_amount} seconds" $dir
30 }
31
32 # Generate a new message in the mail directory, with
33 # a unique message ID and subject.
34 #
35 # The filename of the message generated is available as
36 # $gen_msg_filename
37 #
38 # This function supports named parameters with the bash syntax for
39 # assigning a value to an associative array ([name]=value). The
40 # supported parameters are:
41 #
42 #  [dir]=directory/of/choice
43 #
44 #       Generate the message in directory 'directory/of/choice' within
45 #       the mail store. The directory will be created if necessary.
46 #
47 #  [body]=text
48 #
49 #       Text to use as the body of the email message
50 #
51 #  '[from]="Some User <user@example.com>"'
52 #  '[to]="Some User <user@example.com>"'
53 #  '[subject]="Subject of email message"'
54 #
55 #       Values for email headers. If not provided, default values will
56 #       be generated instead.
57 #
58 #  '[cc]="Some User <user@example.com>"'
59 #  [in-reply-to]=<message-id>
60 #
61 #       Additional values for email headers. If these are not provided
62 #       then the relevant headers will simply not appear in the
63 #       message.
64 gen_msg_cnt=0
65 gen_msg_filename=""
66 generate_message ()
67 {
68     # This is our (bash-specific) magic for doing named parameters
69     local -A template="($@)"
70     local additional_headers
71
72     gen_msg_cnt=$((gen_msg_cnt + 1))
73     gen_msg_name=msg-$(printf "%03d" $gen_msg_cnt)
74
75     if [ -z "${template[dir]}" ]; then
76         gen_msg_filename="${MAIL_DIR}/$gen_msg_name"
77     else
78         gen_msg_filename="${MAIL_DIR}/${template[dir]}/$gen_msg_name"
79         mkdir -p $(dirname $gen_msg_filename)
80     fi
81
82     if [ -z "${template[body]}" ]; then
83         template[body]="This is just a test message at ${gen_msg_filename}"
84     fi
85
86     if [ -z "${template[from]}" ]; then
87         template[from]="Notmuch Test Suite <test_suite@notmuchmail.org>"
88     fi
89
90     if [ -z "${template[to]}" ]; then
91         template[to]="Notmuch Test Suite <test_suite@notmuchmail.org>"
92     fi
93
94     if [ -z "${template[subject]}" ]; then
95         template[subject]="Test message ${gen_msg_filename}"
96     fi
97
98     additional_headers=""
99     if [ ! -z "${template[cc]}" ]; then
100         additional_headers="Cc: ${template[cc]}
101 ${additional_headers}"
102     fi
103
104     if [ ! -z "${template[in-reply-to]}" ]; then
105         additional_headers="In-Reply-To: ${template[in-reply-to]}
106 ${additional_headers}"
107     fi
108
109 cat <<EOF >$gen_msg_filename
110 From: ${template[from]}
111 To: ${template[to]}
112 Message-Id: <msg-${gen_msg_cnt}@notmuch-test-suite>
113 Subject: ${template[subject]}
114 Date: Tue, 05 Jan 2010 15:43:57 -0800
115 ${additional_headers}
116 ${template[body]}
117 EOF
118 }
119
120     # Ensure that the mtime of the containing directory is updated
121     increment_mtime $(dirname ${gen_msg_filename})
122 }
123
124 NOTMUCH_IGNORED_OUTPUT_REGEXP='^Processed [0-9]*( total)? file|Found [0-9]* total file'
125
126 execute_expecting ()
127 {
128     args=$1
129     expected=$2
130
131     output=$($NOTMUCH $args | grep -v -E -e "$NOTMUCH_IGNORED_OUTPUT_REGEXP")
132     if [ "$output" = "$expected" ]; then
133         echo "  PASS"
134     else
135         echo "  FAIL"
136         echo "  Expected output: $expected"
137         echo "  Actual output:   $output"
138     fi
139 }
140
141 TEST_DIR=$(pwd)/test.$$
142 MAIL_DIR=${TEST_DIR}/mail
143 export NOTMUCH_CONFIG=${TEST_DIR}/notmuch-config
144 NOTMUCH=$(find_notmuch_binary $(pwd))
145
146 rm -rf ${TEST_DIR}
147 mkdir ${TEST_DIR}
148 cd ${TEST_DIR}
149
150 mkdir ${MAIL_DIR}
151
152 cat <<EOF > ${NOTMUCH_CONFIG}
153 [database]
154 path=${MAIL_DIR}
155
156 [user]
157 name=Notmuch Test Suite
158 primary_email=test_suite@notmuchmail.org
159 EOF
160
161 printf "Testing \"notmuch new\" in several variations:\n"
162 printf " No new messages...\t\t"
163 execute_expecting new "No new mail."
164
165 printf " Single new message...\t\t"
166 generate_message
167 execute_expecting new "Added 1 new message to the database."
168
169 printf " Multiple new messages...\t"
170 generate_message
171 generate_message
172 execute_expecting new "Added 2 new messages to the database."
173
174 printf " No new messages (non-empty DB)... "
175 execute_expecting new "No new mail."
176
177 printf " New directories...\t\t"
178 rm -rf ${MAIL_DIR}/* ${MAIL_DIR}/.notmuch
179 mkdir ${MAIL_DIR}/def
180 mkdir ${MAIL_DIR}/ghi
181 generate_message [dir]=def
182
183 execute_expecting new "Added 1 new message to the database."
184
185 printf " Alternate inode order...\t"
186
187 rm -rf ${MAIL_DIR}/.notmuch
188 mv ${MAIL_DIR}/ghi ${MAIL_DIR}/abc
189 rm ${MAIL_DIR}/def/*
190 generate_message [dir]=abc
191
192 execute_expecting new "Added 1 new message to the database."
193
194 printf " Message moved in...\t\t"
195 rm -rf ${MAIL_DIR}/* ${MAIL_DIR}/.notmuch
196 generate_message
197 tmp_msg_filename=tmp/$gen_msg_filename
198 mkdir -p $(dirname $tmp_msg_filename)
199 mv $gen_msg_filename $tmp_msg_filename
200 increment_mtime ${MAIL_DIR}
201 $NOTMUCH new > /dev/null
202 mv $tmp_msg_filename $gen_msg_filename
203 increment_mtime ${MAIL_DIR}
204 execute_expecting new "Added 1 new message to the database."
205
206 printf " Renamed message...\t\t"
207
208 generate_message
209 $NOTMUCH new > /dev/null
210 mv $gen_msg_filename ${gen_msg_filename}-renamed
211 increment_mtime ${MAIL_DIR}
212 execute_expecting new "No new mail. Detected 1 file rename."
213
214 printf " Deleted message...\t\t"
215
216 rm ${gen_msg_filename}-renamed
217 increment_mtime ${MAIL_DIR}
218 execute_expecting new "No new mail. Removed 1 message."
219
220 printf " Renamed directory...\t\t"
221
222 generate_message [dir]=dir
223 generate_message [dir]=dir
224 generate_message [dir]=dir
225
226 $NOTMUCH new > /dev/null
227
228 mv ${MAIL_DIR}/dir ${MAIL_DIR}/dir-renamed
229 increment_mtime ${MAIL_DIR}
230
231 execute_expecting new "No new mail. Detected 3 file renames."
232
233 printf " Deleted directory...\t\t"
234
235 rm -rf ${MAIL_DIR}/dir-renamed
236 increment_mtime ${MAIL_DIR}
237
238 execute_expecting new "No new mail. Removed 3 messages."
239
240 printf " New directory (at end of list)... "
241
242 generate_message [dir]=zzz
243 generate_message [dir]=zzz
244 generate_message [dir]=zzz
245
246 execute_expecting new "Added 3 new messages to the database."
247
248 printf " Deleted directory (end of list)... "
249
250 rm -rf ${MAIL_DIR}/zzz
251 increment_mtime ${MAIL_DIR}
252
253 execute_expecting new "No new mail. Removed 3 messages."
254
255 printf " New symlink to directory...\t"
256
257 rm -rf ${MAIL_DIR}/.notmuch
258 mv ${MAIL_DIR} ${TEST_DIR}/actual_maildir
259
260 mkdir ${MAIL_DIR}
261 ln -s ${TEST_DIR}/actual_maildir ${MAIL_DIR}/symlink
262
263 execute_expecting new "Added 1 new message to the database."
264
265 printf " New symlink to a file...\t"
266 generate_message
267 external_msg_filename=${TEST_DIR}/external/$(basename $gen_msg_filename)
268 mkdir -p $(dirname $external_msg_filename)
269 mv $gen_msg_filename $external_msg_filename
270 ln -s $external_msg_filename $gen_msg_filename
271 increment_mtime ${MAIL_DIR}
272 execute_expecting new "Added 1 new message to the database."
273
274 printf " New two-level directory...\t"
275
276 generate_message [dir]=two/levels
277 generate_message [dir]=two/levels
278 generate_message [dir]=two/levels
279
280 execute_expecting new "Added 3 new messages to the database."
281
282 printf " Deleted two-level directory... "
283
284 rm -rf ${MAIL_DIR}/two
285 increment_mtime ${MAIL_DIR}
286
287 execute_expecting new "No new mail. Removed 3 messages."
288
289 cat <<EOF
290 Notmuch test suite complete.
291
292 Intermediate state can be examined in:
293         ${TEST_DIR}
294 EOF