]> git.cworth.org Git - notmuch/blob - test/T566-lib-message.sh
notmuch-mutt: convert ISO-8859-15 copyright statement to UTF-8
[notmuch] / test / T566-lib-message.sh
1 #!/usr/bin/env bash
2 test_description="API tests for notmuch_message_*"
3
4 . $(dirname "$0")/test-lib.sh || exit 1
5
6 add_email_corpus
7
8 test_begin_subtest "building database"
9 test_expect_success "NOTMUCH_NEW"
10
11 cat <<'EOF' > c_tail
12    if (stat) {
13        const char *stat_str = notmuch_database_status_string (db);
14        if (stat_str)
15            fputs (stat_str, stderr);
16     }
17
18 }
19 EOF
20
21 cat <<EOF > c_head0
22 #include <notmuch-test.h>
23
24 int main (int argc, char** argv)
25 {
26    notmuch_database_t *db;
27    notmuch_status_t stat;
28    char *msg = NULL;
29    notmuch_message_t *message = NULL;
30    const char *id = "87pr7gqidx.fsf@yoom.home.cworth.org";
31
32    stat = notmuch_database_open_with_config (argv[1],
33                                              NOTMUCH_DATABASE_MODE_READ_WRITE,
34                                              NULL, NULL, &db, &msg);
35    if (stat != NOTMUCH_STATUS_SUCCESS) {
36      fprintf (stderr, "error opening database: %d %s\n", stat, msg ? msg : "");
37      exit (1);
38    }
39    EXPECT0(notmuch_database_find_message (db, id, &message));
40 EOF
41
42 cp c_head0 c_head
43 echo "   EXPECT0(notmuch_database_close (db));" >> c_head
44
45 test_begin_subtest "Handle getting message-id from closed database"
46 cat c_head - c_tail <<'EOF' | test_C ${MAIL_DIR}
47     {
48         const char *id2;
49         id2=notmuch_message_get_message_id (message);
50         printf("%d\n%d\n", message != NULL, id2==NULL);
51     }
52 EOF
53 cat <<EOF > EXPECTED
54 == stdout ==
55 1
56 1
57 == stderr ==
58 EOF
59 test_expect_equal_file EXPECTED OUTPUT
60
61 test_begin_subtest "Handle getting thread-id from closed database"
62 cat c_head - c_tail <<'EOF' | test_C ${MAIL_DIR}
63     {
64         const char *id2;
65         id2=notmuch_message_get_thread_id (message);
66         printf("%d\n%d\n", message != NULL, id2==NULL);
67     }
68 EOF
69 cat <<EOF > EXPECTED
70 == stdout ==
71 1
72 1
73 == stderr ==
74 EOF
75 test_expect_equal_file EXPECTED OUTPUT
76
77 test_begin_subtest "Handle getting header from closed database"
78 cat c_head - c_tail <<'EOF' | test_C ${MAIL_DIR}
79     {
80         const char *from;
81         from=notmuch_message_get_header (message, "from");
82         printf("%s\n%d\n", id, from == NULL);
83     }
84 EOF
85 cat <<EOF > EXPECTED
86 == stdout ==
87 87pr7gqidx.fsf@yoom.home.cworth.org
88 1
89 == stderr ==
90 EOF
91 test_expect_equal_file EXPECTED OUTPUT
92
93 # XXX this test only tests the trivial code path
94 test_begin_subtest "Handle getting replies from closed database"
95 cat c_head - c_tail <<'EOF' | test_C ${MAIL_DIR}
96     {
97         notmuch_messages_t *replies;
98         replies = notmuch_message_get_replies (message);
99         printf("%d\n%d\n", message != NULL, replies==NULL);
100     }
101 EOF
102 cat <<EOF > EXPECTED
103 == stdout ==
104 1
105 1
106 == stderr ==
107 EOF
108 test_expect_equal_file EXPECTED OUTPUT
109
110 test_begin_subtest "Handle getting message filename from closed database"
111 cat c_head - c_tail <<'EOF' | test_C ${MAIL_DIR}
112     {
113         const char *filename;
114         filename = notmuch_message_get_filename (message);
115         printf("%d\n%d\n", message != NULL, filename == NULL);
116     }
117 EOF
118 cat <<EOF > EXPECTED
119 == stdout ==
120 1
121 1
122 == stderr ==
123 EOF
124 test_expect_equal_file EXPECTED OUTPUT
125
126 test_begin_subtest "Handle getting all message filenames from closed database"
127 cat c_head - c_tail <<'EOF' | test_C ${MAIL_DIR}
128     {
129         notmuch_filenames_t *filenames;
130         filenames = notmuch_message_get_filenames (message);
131         printf("%d\n%d\n", message != NULL, filenames == NULL);
132     }
133 EOF
134 cat <<EOF > EXPECTED
135 == stdout ==
136 1
137 1
138 == stderr ==
139 EOF
140 test_expect_equal_file EXPECTED OUTPUT
141
142 test_begin_subtest "iterate over all message filenames from closed database"
143 cat c_head0 - c_tail <<'EOF' | test_C ${MAIL_DIR}
144     {
145         notmuch_filenames_t *filenames;
146         filenames = notmuch_message_get_filenames (message);
147         EXPECT0(notmuch_database_close (db));
148         for (; notmuch_filenames_valid (filenames);
149                notmuch_filenames_move_to_next (filenames)) {
150             const char *filename = notmuch_filenames_get (filenames);
151             printf("%s\n", filename);
152         }
153         notmuch_filenames_destroy (filenames);
154         printf("SUCCESS\n");
155     }
156 EOF
157 cat <<EOF > EXPECTED
158 == stdout ==
159 MAIL_DIR/cur/40:2,
160 SUCCESS
161 == stderr ==
162 EOF
163 test_expect_equal_file EXPECTED OUTPUT
164
165 test_begin_subtest "Handle getting ghost flag from closed database"
166 cat c_head - c_tail <<'EOF' | test_C ${MAIL_DIR}
167     {
168         notmuch_bool_t result;
169         result = notmuch_message_get_flag (message, NOTMUCH_MESSAGE_FLAG_GHOST);
170         printf("%d\n%d\n", message != NULL, result == FALSE);
171     }
172 EOF
173 cat <<EOF > EXPECTED
174 == stdout ==
175 1
176 1
177 == stderr ==
178 EOF
179 test_expect_equal_file EXPECTED OUTPUT
180
181 test_begin_subtest "Handle getting date from closed database"
182 cat c_head - c_tail <<'EOF' | test_C ${MAIL_DIR}
183     {
184         time_t result;
185         result = notmuch_message_get_date (message);
186         printf("%d\n%d\n", message != NULL, result == 0);
187     }
188 EOF
189 cat <<EOF > EXPECTED
190 == stdout ==
191 1
192 1
193 == stderr ==
194 EOF
195 test_expect_equal_file EXPECTED OUTPUT
196
197 test_begin_subtest "Handle getting tags from closed database"
198 cat c_head - c_tail <<'EOF' | test_C ${MAIL_DIR}
199     {
200         notmuch_tags_t *result;
201         result = notmuch_message_get_tags (message);
202         printf("%d\n%d\n", message != NULL, result == NULL);
203     }
204 EOF
205 cat <<EOF > EXPECTED
206 == stdout ==
207 1
208 1
209 == stderr ==
210 EOF
211 test_expect_equal_file EXPECTED OUTPUT
212
213 test_begin_subtest "Handle counting files from closed database"
214 cat c_head - c_tail <<'EOF' | test_C ${MAIL_DIR}
215     {
216         int result;
217         result = notmuch_message_count_files (message);
218         printf("%d\n%d\n", message != NULL, result < 0);
219     }
220 EOF
221 cat <<EOF > EXPECTED
222 == stdout ==
223 1
224 1
225 == stderr ==
226 EOF
227 test_expect_equal_file EXPECTED OUTPUT
228
229 test_begin_subtest "Handle adding tag with closed database"
230 cat c_head - c_tail <<'EOF' | test_C ${MAIL_DIR}
231     {
232         notmuch_status_t status;
233         status = notmuch_message_add_tag (message, "boom");
234         printf("%d\n%d\n", message != NULL, status == NOTMUCH_STATUS_CLOSED_DATABASE);
235     }
236 EOF
237 cat <<EOF > EXPECTED
238 == stdout ==
239 1
240 1
241 == stderr ==
242 EOF
243 test_expect_equal_file EXPECTED OUTPUT
244
245 test_begin_subtest "Handle removing tag with closed database"
246 cat c_head - c_tail <<'EOF' | test_C ${MAIL_DIR}
247     {
248         notmuch_status_t status;
249         status = notmuch_message_remove_tag (message, "boom");
250         printf("%d\n%d\n", message != NULL, status == NOTMUCH_STATUS_CLOSED_DATABASE);
251     }
252 EOF
253 cat <<EOF > EXPECTED
254 == stdout ==
255 1
256 1
257 == stderr ==
258 EOF
259 test_expect_equal_file EXPECTED OUTPUT
260
261 test_begin_subtest "Handle read maildir flag with closed database"
262 cat c_head - c_tail <<'EOF' | test_C ${MAIL_DIR}
263     {
264         notmuch_bool_t is_set = -1;
265         is_set = notmuch_message_has_maildir_flag (message, 'S');
266         printf("%d\n%d\n", message != NULL, is_set == FALSE || is_set == TRUE);
267     }
268 EOF
269 cat <<EOF > EXPECTED
270 == stdout ==
271 1
272 1
273 == stderr ==
274 EOF
275 test_expect_equal_file EXPECTED OUTPUT
276
277 test_begin_subtest "Handle checking maildir flag with closed db (new API)"
278 cat c_head - c_tail <<'EOF' | test_C ${MAIL_DIR}
279     {
280         notmuch_status_t status;
281         notmuch_bool_t out;
282         status = notmuch_message_has_maildir_flag_st (message, 'S', &out);
283         printf("%d\n%d\n", message != NULL, status == NOTMUCH_STATUS_XAPIAN_EXCEPTION);
284     }
285 EOF
286 cat <<EOF > EXPECTED
287 == stdout ==
288 1
289 1
290 == stderr ==
291 EOF
292 test_expect_equal_file EXPECTED OUTPUT
293
294 test_begin_subtest "Handle converting maildir flags to tags with closed db"
295 cat c_head - c_tail <<'EOF' | test_C ${MAIL_DIR}
296     {
297         notmuch_status_t status;
298         status = notmuch_message_maildir_flags_to_tags (message);
299         printf("%d\n%d\n", message != NULL, status == NOTMUCH_STATUS_XAPIAN_EXCEPTION);
300     }
301 EOF
302 cat <<EOF > EXPECTED
303 == stdout ==
304 1
305 1
306 == stderr ==
307 EOF
308 test_expect_equal_file EXPECTED OUTPUT
309
310 test_begin_subtest "_notmuch_message_add_term catches exceptions"
311 cat c_head0 - c_tail <<'EOF' | test_private_C ${MAIL_DIR}
312     {
313         notmuch_private_status_t status;
314         /* This relies on Xapian throwing an exception for adding empty terms */
315         status = _notmuch_message_add_term (message, "body", "");
316         printf("%d\n%d\n", message != NULL, status != NOTMUCH_STATUS_SUCCESS );
317     }
318 EOF
319 cat <<EOF > EXPECTED
320 == stdout ==
321 1
322 1
323 == stderr ==
324 EOF
325 test_expect_equal_file EXPECTED OUTPUT
326
327 test_begin_subtest "_notmuch_message_remove_term catches exceptions"
328 cat c_head0 - c_tail <<'EOF' | test_private_C ${MAIL_DIR}
329     {
330         notmuch_private_status_t status;
331         /* Xapian throws the same exception for empty and non-existent terms;
332          * error string varies between Xapian versions. */
333         status = _notmuch_message_remove_term (message, "tag", "nonexistent");
334         printf("%d\n%d\n", message != NULL, status == NOTMUCH_STATUS_SUCCESS );
335     }
336 EOF
337 cat <<EOF > EXPECTED
338 == stdout ==
339 1
340 1
341 == stderr ==
342 EOF
343 test_expect_equal_file EXPECTED OUTPUT
344
345 test_begin_subtest "_notmuch_message_add_filename on closed db"
346 cat c_head - c_tail <<'EOF' | test_private_C ${MAIL_DIR}
347     {
348         notmuch_private_status_t status;
349         status = _notmuch_message_add_filename (message, "some-filename");
350         printf("%d\n%d\n", message != NULL, status != NOTMUCH_STATUS_SUCCESS);
351     }
352 EOF
353 cat <<EOF > EXPECTED
354 == stdout ==
355 1
356 1
357 == stderr ==
358 EOF
359 test_expect_equal_file EXPECTED OUTPUT
360
361 test_begin_subtest "_notmuch_message_remove_filename on closed db"
362 cat c_head - c_tail <<'EOF' | test_private_C ${MAIL_DIR}
363     {
364         notmuch_private_status_t status;
365         status = _notmuch_message_remove_filename (message, "some-filename");
366         printf("%d\n%d\n", message != NULL, status != NOTMUCH_STATUS_SUCCESS);
367     }
368 EOF
369 cat <<EOF > EXPECTED
370 == stdout ==
371 1
372 1
373 == stderr ==
374 EOF
375 test_expect_equal_file EXPECTED OUTPUT
376
377 test_begin_subtest "Handle converting tags to maildir flags with closed db"
378 cat c_head - c_tail <<'EOF' | test_C ${MAIL_DIR}
379     {
380         notmuch_status_t status;
381         status = notmuch_message_tags_to_maildir_flags (message);
382         printf("%d\n%d\n", message != NULL, status != NOTMUCH_STATUS_SUCCESS);
383     }
384 EOF
385 cat <<EOF > EXPECTED
386 == stdout ==
387 1
388 1
389 == stderr ==
390 EOF
391 test_expect_equal_file EXPECTED OUTPUT
392
393 POSTLIST_PATH=(${MAIL_DIR}/.notmuch/xapian/postlist.*)
394 test_begin_subtest "Handle converting tags to maildir flags with corrupted db"
395 backup_database
396 cat c_head0 - c_tail <<'EOF' | test_C ${MAIL_DIR} ${POSTLIST_PATH}
397     {
398         notmuch_status_t status;
399
400         status = notmuch_message_add_tag (message, "draft");
401         if (status) exit(1);
402
403         int fd = open(argv[2],O_WRONLY|O_TRUNC);
404         if (fd < 0) {
405             fprintf (stderr, "error opening %s\n", argv[1]);
406             exit (1);
407         }
408
409         status = notmuch_message_tags_to_maildir_flags (message);
410         printf("%d\n%d\n", message != NULL, status != NOTMUCH_STATUS_SUCCESS);
411     }
412 EOF
413 cat <<EOF > EXPECTED
414 == stdout ==
415 1
416 1
417 == stderr ==
418 EOF
419 restore_database
420 notmuch new
421 notmuch tag -draft id:87pr7gqidx.fsf@yoom.home.cworth.org
422 test_expect_equal_file EXPECTED OUTPUT
423
424 test_begin_subtest "Handle removing all tags with closed db"
425 cat c_head - c_tail <<'EOF' | test_C ${MAIL_DIR}
426     {
427         notmuch_status_t status;
428         status = notmuch_message_remove_all_tags (message);
429         printf("%d\n%d\n", message != NULL, status == NOTMUCH_STATUS_CLOSED_DATABASE);
430     }
431 EOF
432 cat <<EOF > EXPECTED
433 == stdout ==
434 1
435 1
436 == stderr ==
437 EOF
438 test_expect_equal_file EXPECTED OUTPUT
439
440 test_begin_subtest "Handle freezing message with closed db"
441 cat c_head - c_tail <<'EOF' | test_C ${MAIL_DIR}
442     {
443         notmuch_status_t status;
444         status = notmuch_message_freeze (message);
445         printf("%d\n%d\n", message != NULL, status == NOTMUCH_STATUS_CLOSED_DATABASE);
446     }
447 EOF
448 cat <<EOF > EXPECTED
449 == stdout ==
450 1
451 1
452 == stderr ==
453 EOF
454 test_expect_equal_file EXPECTED OUTPUT
455
456 test_begin_subtest "Handle thawing message with closed db"
457 cat c_head - c_tail <<'EOF' | test_C ${MAIL_DIR}
458     {
459         notmuch_status_t status;
460         status = notmuch_message_thaw (message);
461         printf("%d\n%d\n", message != NULL, status == NOTMUCH_STATUS_CLOSED_DATABASE);
462     }
463 EOF
464 cat <<EOF > EXPECTED
465 == stdout ==
466 1
467 1
468 == stderr ==
469 EOF
470 test_expect_equal_file EXPECTED OUTPUT
471
472 test_begin_subtest "Handle destroying message with closed db"
473 cat c_head - c_tail <<'EOF' | test_C ${MAIL_DIR}
474     {
475         notmuch_message_destroy (message);
476         printf("%d\n%d\n", message != NULL, 1);
477     }
478 EOF
479 cat <<EOF > EXPECTED
480 == stdout ==
481 1
482 1
483 == stderr ==
484 EOF
485 test_expect_equal_file EXPECTED OUTPUT
486
487 test_begin_subtest "Handle retrieving closed db from message"
488 cat c_head - c_tail <<'EOF' | test_C ${MAIL_DIR}
489     {
490         notmuch_database_t *db2;
491         db2 = notmuch_message_get_database (message);
492         printf("%d\n%d\n", message != NULL, db == db2);
493     }
494 EOF
495 cat <<EOF > EXPECTED
496 == stdout ==
497 1
498 1
499 == stderr ==
500 EOF
501 test_expect_equal_file EXPECTED OUTPUT
502
503 test_begin_subtest "Handle reindexing message with closed db"
504 cat c_head - c_tail <<'EOF' | test_C ${MAIL_DIR}
505     {
506         notmuch_status_t status;
507         status = notmuch_message_reindex (message, NULL);
508         printf("%d\n%d\n", message != NULL, status == NOTMUCH_STATUS_XAPIAN_EXCEPTION);
509     }
510 EOF
511 cat <<EOF > EXPECTED
512 == stdout ==
513 1
514 1
515 == stderr ==
516 EOF
517 test_expect_equal_file EXPECTED OUTPUT
518
519 TERMLIST_PATH=(${MAIL_DIR}/.notmuch/xapian/termlist.*)
520 test_begin_subtest "remove message with corrupted db"
521 backup_database
522 cat c_head0 - c_tail <<'EOF' | test_private_C ${MAIL_DIR} ${TERMLIST_PATH}
523     {
524         notmuch_status_t status;
525
526         int fd = open(argv[2],O_WRONLY|O_TRUNC);
527         if (fd < 0) {
528             fprintf (stderr, "error opening %s\n", argv[1]);
529             exit (1);
530         }
531
532         stat = _notmuch_message_delete (message);
533         printf ("%d\n", stat == NOTMUCH_STATUS_XAPIAN_EXCEPTION);
534     }
535 EOF
536 cat <<EOF > EXPECTED
537 == stdout ==
538 1
539 == stderr ==
540 A Xapian exception occurred at message.cc:XXX: EOF reading block YYY
541 EOF
542 sed 's/EOF reading block [0-9]*/EOF reading block YYY/' < OUTPUT > OUTPUT.clean
543 test_expect_equal_file EXPECTED OUTPUT.clean
544 restore_database
545
546 test_done