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
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
| | #!/usr/bin/env bash
test_description='"notmuch insert"'
. $(dirname "$0")/test-lib.sh || exit 1
test_require_external_prereq gdb
# subtests about file permissions assume that we're working with umask
# 022 by default.
umask 022
# Create directories and database before inserting.
mkdir -p "$MAIL_DIR"/{cur,new,tmp}
mkdir -p "$MAIL_DIR"/Drafts/{cur,new,tmp}
notmuch new > /dev/null
# We use generate_message to create the temporary message files.
# They happen to be in the mail directory already but that is okay
# since we do not call notmuch new hereafter.
gen_insert_msg() {
generate_message \
"[subject]=\"insert-subject\"" \
"[date]=\"Sat, 01 Jan 2000 12:00:00 -0000\"" \
"[body]=\"insert-message\""
}
test_begin_subtest "Insert zero-length file"
test_expect_code 1 "notmuch insert < /dev/null"
# This test is a proxy for other errors that may occur while trying to
# add a message to the notmuch database, e.g. database locked.
test_begin_subtest "Insert non-message"
test_expect_code 1 "echo bad_message | notmuch insert"
test_begin_subtest "Database empty so far"
test_expect_equal "0" "`notmuch count --output=messages '*'`"
test_begin_subtest "Insert message"
gen_insert_msg
notmuch insert < "$gen_msg_filename"
cur_msg_filename=$(notmuch search --output=files "subject:insert-subject")
test_expect_equal_file "$cur_msg_filename" "$gen_msg_filename"
test_begin_subtest "Permissions on inserted message should be 0600"
test_expect_equal "600" "$(stat -c %a "$cur_msg_filename")"
test_begin_subtest "Insert message adds default tags"
output=$(notmuch show --format=json "subject:insert-subject")
expected='[[[{
"id": "'"${gen_msg_id}"'",
"match": true,
"excluded": false,
"filename": ["'"${cur_msg_filename}"'"],
"timestamp": 946728000,
"date_relative": "2000-01-01",
"tags": ["inbox","unread"],
"headers": {
"Subject": "insert-subject",
"From": "Notmuch Test Suite <test_suite@notmuchmail.org>",
"To": "Notmuch Test Suite <test_suite@notmuchmail.org>",
"Date": "Sat, 01 Jan 2000 12:00:00 +0000"},
"body": [{"id": 1,
"content-type": "text/plain",
"content": "insert-message\n"}]},
[]]]]'
test_expect_equal_json "$output" "$expected"
test_begin_subtest "Insert duplicate message"
notmuch insert +duptag -unread < "$gen_msg_filename"
output=$((`notmuch search --output=files "subject:insert-subject" | wc -l`))
test_expect_equal "$output" 2
test_begin_subtest "Duplicate message does not change tags"
output=$(notmuch search --format=json --output=tags "subject:insert-subject")
test_expect_equal_json "$output" '["inbox", "unread"]'
test_begin_subtest "Insert message, add tag"
gen_insert_msg
notmuch insert +custom < "$gen_msg_filename"
output=$(notmuch search --output=messages tag:custom)
test_expect_equal "$output" "id:$gen_msg_id"
test_begin_subtest "Insert tagged world-readable message"
gen_insert_msg
notmuch insert --world-readable +world-readable-test < "$gen_msg_filename"
cur_msg_filename=$(notmuch search --output=files "tag:world-readable-test")
test_expect_equal_file "$cur_msg_filename" "$gen_msg_filename"
test_begin_subtest "Permissions on inserted world-readable message should be 0644"
test_expect_equal "644" "$(stat -c %a "$cur_msg_filename")"
test_begin_subtest "Insert tagged world-readable message with group-only umask"
oldumask=$(umask)
umask 027
gen_insert_msg
notmuch insert --world-readable +world-readable-umask-test < "$gen_msg_filename"
cur_msg_filename=$(notmuch search --output=files "tag:world-readable-umask-test")
umask "$oldumask"
test_expect_equal_file "$cur_msg_filename" "$gen_msg_filename"
test_begin_subtest "Permissions on inserted world-readable message with funny umask should be 0640"
test_expect_equal "640" "$(stat -c %a "$cur_msg_filename")"
test_begin_subtest "Insert message, add/remove tags"
gen_insert_msg
notmuch insert +custom -unread < "$gen_msg_filename"
output=$(notmuch search --output=messages tag:custom NOT tag:unread)
test_expect_equal "$output" "id:$gen_msg_id"
test_begin_subtest "Insert message with default tags stays in new/"
gen_insert_msg
notmuch insert < "$gen_msg_filename"
output=$(notmuch search --output=files id:$gen_msg_id)
dirname=$(dirname "$output")
test_expect_equal "$dirname" "$MAIL_DIR/new"
test_begin_subtest "Insert message with non-maildir synced tags stays in new/"
gen_insert_msg
notmuch insert +custom -inbox < "$gen_msg_filename"
output=$(notmuch search --output=files id:$gen_msg_id)
dirname=$(dirname "$output")
test_expect_equal "$dirname" "$MAIL_DIR/new"
test_begin_subtest "Insert message with custom new.tags goes to cur/"
OLDCONFIG=$(notmuch config get new.tags)
notmuch config set new.tags test
gen_insert_msg
notmuch insert < "$gen_msg_filename"
output=$(notmuch search --output=files id:$gen_msg_id)
dirname=$(dirname "$output")
notmuch config set new.tags $OLDCONFIG
test_expect_equal "$dirname" "$MAIL_DIR/cur"
# additional check on the previous message
test_begin_subtest "Insert message with custom new.tags actually gets the tags"
output=$(notmuch search --output=tags id:$gen_msg_id)
test_expect_equal "$output" "test"
test_begin_subtest "Insert message with maildir synced tags goes to cur/"
gen_insert_msg
notmuch insert +flagged < "$gen_msg_filename"
output=$(notmuch search --output=files id:$gen_msg_id)
dirname=$(dirname "$output")
test_expect_equal "$dirname" "$MAIL_DIR/cur"
test_begin_subtest "Insert message with maildir sync off goes to new/"
OLDCONFIG=$(notmuch config get maildir.synchronize_flags)
notmuch config set maildir.synchronize_flags false
gen_insert_msg
notmuch insert +flagged < "$gen_msg_filename"
output=$(notmuch search --output=files id:$gen_msg_id)
dirname=$(dirname "$output")
notmuch config set maildir.synchronize_flags $OLDCONFIG
test_expect_equal "$dirname" "$MAIL_DIR/new"
test_begin_subtest "Insert message into folder"
gen_insert_msg
notmuch insert --folder=Drafts < "$gen_msg_filename"
output=$(notmuch search --output=files path:Drafts/new)
dirname=$(dirname "$output")
test_expect_equal "$dirname" "$MAIL_DIR/Drafts/new"
test_begin_subtest "Insert message into top level folder"
gen_insert_msg
notmuch insert --folder="" < "$gen_msg_filename"
output=$(notmuch search --output=files id:${gen_msg_id})
dirname=$(dirname "$output")
test_expect_equal "$dirname" "$MAIL_DIR/new"
test_begin_subtest "Insert message into folder with trailing /"
gen_insert_msg
notmuch insert --folder=Drafts/ < "$gen_msg_filename"
output=$(notmuch search --output=files id:${gen_msg_id})
dirname=$(dirname "$output")
test_expect_equal "$dirname" "$MAIL_DIR/Drafts/new"
test_begin_subtest "Insert message into folder, add/remove tags"
gen_insert_msg
notmuch insert --folder=Drafts +draft -unread < "$gen_msg_filename"
output=$(notmuch search --output=messages path:Drafts/cur tag:draft NOT tag:unread)
test_expect_equal "$output" "id:$gen_msg_id"
test_begin_subtest "Insert message into non-existent folder"
gen_insert_msg
test_expect_code 1 "notmuch insert --folder=nonesuch < $gen_msg_filename"
test_begin_subtest "Insert message, create folder"
gen_insert_msg
notmuch insert --folder=F --create-folder +folder < "$gen_msg_filename"
output=$(notmuch search --output=files path:F/new tag:folder)
basename=$(basename "$output")
test_expect_equal_file "$gen_msg_filename" "$MAIL_DIR/F/new/${basename}"
test_begin_subtest "Insert message, create subfolder"
gen_insert_msg
notmuch insert --folder=F/G/H/I/J --create-folder +folder < "$gen_msg_filename"
output=$(notmuch search --output=files path:F/G/H/I/J/new tag:folder)
basename=$(basename "$output")
test_expect_equal_file "$gen_msg_filename" "${MAIL_DIR}/F/G/H/I/J/new/${basename}"
test_begin_subtest "Created subfolder should have permissions 0700"
test_expect_equal "700" "$(stat -c %a "${MAIL_DIR}/F/G/H/I/J")"
test_begin_subtest "Created subfolder new/ should also have permissions 0700"
test_expect_equal "700" "$(stat -c %a "${MAIL_DIR}/F/G/H/I/J/new")"
test_begin_subtest "Insert message, create world-readable subfolder"
gen_insert_msg
notmuch insert --folder=F/G/H/I/J/K --create-folder --world-readable +folder-world-readable < "$gen_msg_filename"
output=$(notmuch search --output=files path:F/G/H/I/J/K/new tag:folder-world-readable)
basename=$(basename "$output")
test_expect_equal_file "$gen_msg_filename" "${MAIL_DIR}/F/G/H/I/J/K/new/${basename}"
test_begin_subtest "Created world-readable subfolder should have permissions 0755"
test_expect_equal "755" "$(stat -c %a "${MAIL_DIR}/F/G/H/I/J/K")"
test_begin_subtest "Created world-readable subfolder new/ should also have permissions 0755"
test_expect_equal "755" "$(stat -c %a "${MAIL_DIR}/F/G/H/I/J/K/new")"
test_begin_subtest "Insert message, create existing subfolder"
gen_insert_msg
notmuch insert --folder=F/G/H/I/J --create-folder +folder < "$gen_msg_filename"
output=$(notmuch count path:F/G/H/I/J/new tag:folder)
test_expect_equal "$output" "2"
test_begin_subtest "Insert message, create invalid subfolder"
gen_insert_msg
test_expect_code 1 "notmuch insert --folder=../G --create-folder $gen_msg_filename"
OLDCONFIG=$(notmuch config get new.tags)
test_begin_subtest "Empty tags in new.tags are forbidden"
notmuch config set new.tags "foo;;bar"
gen_insert_msg
output=$(notmuch insert $gen_msg_filename 2>&1)
test_expect_equal "$output" "Error: tag '' in new.tags: empty tag forbidden"
test_begin_subtest "Tags starting with '-' in new.tags are forbidden"
notmuch config set new.tags "-foo;bar"
gen_insert_msg
output=$(notmuch insert $gen_msg_filename 2>&1)
test_expect_equal "$output" "Error: tag '-foo' in new.tags: tag starting with '-' forbidden"
test_begin_subtest "Invalid tags set exit code"
test_expect_code 1 "notmuch insert $gen_msg_filename 2>&1"
notmuch config set new.tags $OLDCONFIG
# DUPLICATE_MESSAGE_ID is not tested here, because it should actually pass.
for code in OUT_OF_MEMORY XAPIAN_EXCEPTION FILE_NOT_EMAIL \
READ_ONLY_DATABASE UPGRADE_REQUIRED PATH_ERROR; do
cat <<EOF > index-file-$code.gdb
set breakpoint pending on
set logging file index-file-$code.log
set logging on
break notmuch_database_index_file
commands
return NOTMUCH_STATUS_$code
continue
end
run
EOF
done
gen_insert_msg
for code in FILE_NOT_EMAIL READ_ONLY_DATABASE UPGRADE_REQUIRED PATH_ERROR; do
test_begin_subtest "EXIT_FAILURE when index_file returns $code"
test_expect_code 1 \
"${TEST_GDB} --batch-silent --return-child-result \
-ex 'set args insert < $gen_msg_filename' \
-x index-file-$code.gdb notmuch"
test_begin_subtest "success exit with --keep when index_file returns $code"
test_expect_code 0 \
"${TEST_GDB} --batch-silent --return-child-result \
-ex 'set args insert --keep < $gen_msg_filename' \
-x index-file-$code.gdb notmuch"
done
for code in OUT_OF_MEMORY XAPIAN_EXCEPTION ; do
test_begin_subtest "EX_TEMPFAIL when index_file returns $code"
test_expect_code 75 \
"${TEST_GDB} --batch-silent --return-child-result \
-ex 'set args insert < $gen_msg_filename' \
-x index-file-$code.gdb notmuch"
test_begin_subtest "success exit with --keep when index_file returns $code"
test_expect_code 0 \
"${TEST_GDB} --batch-silent --return-child-result \
-ex 'set args insert --keep < $gen_msg_filename' \
-x index-file-$code.gdb notmuch"
done
test_done
|