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