ce3526a406b5f88e481bce2f76b01e38efe4bb06
[notmuch] / test / T560-lib-error.sh
1 #!/usr/bin/env bash
2 test_description="error reporting for library"
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 test_begin_subtest "Open null pointer"
12 test_C <<'EOF'
13 #include <stdio.h>
14 #include <notmuch.h>
15 int main (int argc, char** argv)
16 {
17     notmuch_database_t *db;
18     notmuch_status_t stat;
19     stat = notmuch_database_open (NULL, 0, 0);
20 }
21 EOF
22 cat <<'EOF' >EXPECTED
23 == stdout ==
24 == stderr ==
25 Error: Cannot open a database for a NULL path.
26 EOF
27 test_expect_equal_file EXPECTED OUTPUT
28
29 test_begin_subtest "Open relative path"
30 test_C <<'EOF'
31 #include <stdio.h>
32 #include <notmuch.h>
33 int main (int argc, char** argv)
34 {
35     notmuch_database_t *db;
36     notmuch_status_t stat;
37     stat = notmuch_database_open ("./nonexistent/foo", 0, 0);
38 }
39 EOF
40 cat <<'EOF' >EXPECTED
41 == stdout ==
42 == stderr ==
43 Error: Database path must be absolute.
44 EOF
45 test_expect_equal_file EXPECTED OUTPUT
46
47 test_begin_subtest "Create database in relative path"
48 test_C <<'EOF'
49 #include <stdio.h>
50 #include <notmuch.h>
51 int main (int argc, char** argv)
52 {
53     notmuch_database_t *db;
54     notmuch_status_t stat;
55     stat = notmuch_database_create ("./nonexistent/foo", &db);
56 }
57 EOF
58 cat <<'EOF' >EXPECTED
59 == stdout ==
60 == stderr ==
61 Error: Database path must be absolute.
62 EOF
63 test_expect_equal_file EXPECTED OUTPUT
64
65 test_begin_subtest "Open nonexistent database"
66 test_C ${PWD}/nonexistent/foo <<'EOF'
67 #include <stdio.h>
68 #include <notmuch.h>
69 int main (int argc, char** argv)
70 {
71     notmuch_database_t *db;
72     notmuch_status_t stat;
73     stat = notmuch_database_open (argv[1], 0, 0);
74 }
75 EOF
76 cat <<'EOF' >EXPECTED
77 == stdout ==
78 == stderr ==
79 Error opening database at CWD/nonexistent/foo/.notmuch: No such file or directory
80 EOF
81 test_expect_equal_file EXPECTED OUTPUT
82
83 test_begin_subtest "create NULL path"
84 test_C <<'EOF'
85 #include <stdio.h>
86 #include <notmuch.h>
87 int main (int argc, char** argv)
88 {
89     notmuch_status_t stat;
90     stat = notmuch_database_create (NULL, NULL);
91 }
92 EOF
93 cat <<'EOF' >EXPECTED
94 == stdout ==
95 == stderr ==
96 Error: Cannot create a database for a NULL path.
97 EOF
98 test_expect_equal_file EXPECTED OUTPUT
99
100 test_begin_subtest "Create database in nonexistent directory"
101 test_C ${PWD}/nonexistent/foo<<'EOF'
102 #include <stdio.h>
103 #include <notmuch.h>
104 int main (int argc, char** argv)
105 {
106     notmuch_database_t *db;
107     notmuch_status_t stat;
108     stat = notmuch_database_create (argv[1], &db);
109 }
110 EOF
111 cat <<'EOF' >EXPECTED
112 == stdout ==
113 == stderr ==
114 Error: Cannot create database at CWD/nonexistent/foo: No such file or directory.
115 EOF
116 test_expect_equal_file EXPECTED OUTPUT
117
118 test_begin_subtest "Write to read-only database"
119 test_C ${MAIL_DIR} <<'EOF'
120 #include <stdio.h>
121 #include <notmuch.h>
122 int main (int argc, char** argv)
123 {
124    notmuch_database_t *db;
125    notmuch_status_t stat;
126    stat = notmuch_database_open (argv[1], NOTMUCH_DATABASE_MODE_READ_ONLY, &db);
127    if (stat != NOTMUCH_STATUS_SUCCESS) {
128      fprintf (stderr, "error opening database: %d\n", stat);
129    }
130    stat = notmuch_database_index_file (db, "/dev/null", NULL, NULL);
131    if (stat)
132        fputs (notmuch_database_status_string (db), stderr);
133
134 }
135 EOF
136 cat <<'EOF' >EXPECTED
137 == stdout ==
138 == stderr ==
139 Cannot write to a read-only database.
140 EOF
141 test_expect_equal_file EXPECTED OUTPUT
142
143 test_begin_subtest "Add non-existent file"
144 test_C ${MAIL_DIR} <<'EOF'
145 #include <stdio.h>
146 #include <notmuch.h>
147 int main (int argc, char** argv)
148 {
149    notmuch_database_t *db;
150    notmuch_status_t stat;
151    stat = notmuch_database_open (argv[1], NOTMUCH_DATABASE_MODE_READ_WRITE, &db);
152    if (stat != NOTMUCH_STATUS_SUCCESS) {
153      fprintf (stderr, "error opening database: %d\n", stat);
154    }
155    stat = notmuch_database_index_file (db, "./nonexistent", NULL, NULL);
156    if (stat) {
157        char *status_string = notmuch_database_status_string (db);
158        if (status_string) fputs (status_string, stderr);
159    }
160 }
161 EOF
162 cat <<'EOF' >EXPECTED
163 == stdout ==
164 == stderr ==
165 Error opening ./nonexistent: No such file or directory
166 EOF
167 test_expect_equal_file EXPECTED OUTPUT
168
169 test_begin_subtest "compact, overwriting existing backup"
170 test_C ${MAIL_DIR} <<'EOF'
171 #include <stdio.h>
172 #include <notmuch.h>
173 static void
174 status_cb (const char *msg, void *closure)
175 {
176     printf ("%s\n", msg);
177 }
178 int main (int argc, char** argv)
179 {
180    notmuch_database_t *db;
181    notmuch_status_t stat;
182    stat = notmuch_database_compact (argv[1], argv[1], status_cb, NULL);
183 }
184 EOF
185 cat <<'EOF' >EXPECTED
186 == stdout ==
187 Path already exists: MAIL_DIR
188
189 == stderr ==
190 EOF
191 test_expect_equal_file EXPECTED OUTPUT
192
193 cat <<EOF > c_head
194 #include <stdio.h>
195 #include <sys/types.h>
196 #include <sys/stat.h>
197 #include <fcntl.h>
198 #include <talloc.h>
199 #include <notmuch.h>
200
201 int main (int argc, char** argv)
202 {
203    notmuch_database_t *db;
204    notmuch_status_t stat;
205    char *path;
206    char *msg = NULL;
207    int fd;
208
209    stat = notmuch_database_open_verbose (argv[1], NOTMUCH_DATABASE_MODE_READ_WRITE, &db, &msg);
210    if (stat != NOTMUCH_STATUS_SUCCESS) {
211      fprintf (stderr, "error opening database: %d %s\n", stat, msg ? msg : "");
212      exit (1);
213    }
214    path = talloc_asprintf (db, "%s/.notmuch/xapian/postlist.${db_ending}", argv[1]);
215    fd = open(path,O_WRONLY|O_TRUNC);
216    if (fd < 0) {
217        fprintf (stderr, "error opening %s\n", argv[1]);
218        exit (1);
219    }
220 EOF
221 cat <<'EOF' > c_tail
222    if (stat) {
223        const char *stat_str = notmuch_database_status_string (db);
224        if (stat_str)
225            fputs (stat_str, stderr);
226     }
227
228 }
229 EOF
230
231 backup_database
232 test_begin_subtest "Xapian exception finding message"
233 cat c_head - c_tail <<'EOF' | test_C ${MAIL_DIR}
234    {
235        notmuch_message_t *message = NULL;
236        stat = notmuch_database_find_message (db, "id:nonexistent", &message);
237    }
238 EOF
239 sed 's/^\(A Xapian exception [^:]*\):.*$/\1/' < OUTPUT > OUTPUT.clean
240 cat <<'EOF' >EXPECTED
241 == stdout ==
242 == stderr ==
243 A Xapian exception occurred finding message
244 EOF
245 test_expect_equal_file EXPECTED OUTPUT.clean
246 restore_database
247
248 backup_database
249 test_begin_subtest "Xapian exception getting tags"
250 cat c_head - c_tail <<'EOF' | test_C ${MAIL_DIR}
251    {
252        notmuch_tags_t *tags = NULL;
253        tags = notmuch_database_get_all_tags (db);
254        stat = (tags == NULL);
255    }
256 EOF
257 sed 's/^\(A Xapian exception [^:]*\):.*$/\1/' < OUTPUT > OUTPUT.clean
258 cat <<'EOF' >EXPECTED
259 == stdout ==
260 == stderr ==
261 A Xapian exception occurred getting tags
262 EOF
263 test_expect_equal_file EXPECTED OUTPUT.clean
264 restore_database
265
266 backup_database
267 test_begin_subtest "Xapian exception creating directory"
268 cat c_head - c_tail <<'EOF' | test_C ${MAIL_DIR}
269    {
270        notmuch_directory_t *directory = NULL;
271        stat = notmuch_database_get_directory (db, "none/existing", &directory);
272    }
273 EOF
274 sed 's/^\(A Xapian exception [^:]*\):.*$/\1/' < OUTPUT > OUTPUT.clean
275 cat <<'EOF' >EXPECTED
276 == stdout ==
277 == stderr ==
278 A Xapian exception occurred creating a directory
279 EOF
280 test_expect_equal_file EXPECTED OUTPUT.clean
281 restore_database
282
283 backup_database
284 test_begin_subtest "Xapian exception searching messages"
285 cat c_head - c_tail <<'EOF' | test_C ${MAIL_DIR}
286    {
287        notmuch_messages_t *messages = NULL;
288        notmuch_query_t *query=notmuch_query_create (db, "*");
289        stat = notmuch_query_search_messages (query, &messages);
290    }
291 EOF
292 sed 's/^\(A Xapian exception [^:]*\):.*$/\1/' < OUTPUT > OUTPUT.clean
293 cat <<'EOF' >EXPECTED
294 == stdout ==
295 == stderr ==
296 A Xapian exception occurred performing query
297 Query string was: *
298 EOF
299 test_expect_equal_file EXPECTED OUTPUT.clean
300 restore_database
301
302 backup_database
303 test_begin_subtest "Xapian exception counting messages"
304 cat c_head - c_tail <<'EOF' | test_C ${MAIL_DIR}
305    {
306        int count;
307        notmuch_query_t *query=notmuch_query_create (db, "id:87ocn0qh6d.fsf@yoom.home.cworth.org");
308        stat = notmuch_query_count_messages (query, &count);
309    }
310 EOF
311 sed 's/^\(A Xapian exception [^:]*\):.*$/\1/' < OUTPUT > OUTPUT.clean
312 cat <<'EOF' >EXPECTED
313 == stdout ==
314 == stderr ==
315 A Xapian exception occurred performing query
316 Query string was: id:87ocn0qh6d.fsf@yoom.home.cworth.org
317 EOF
318 test_expect_equal_file EXPECTED OUTPUT.clean
319 restore_database
320
321 cat <<EOF > c_head2
322 #include <stdio.h>
323 #include <notmuch.h>
324 #include <notmuch-test.h>
325 int main (int argc, char** argv)
326 {
327    notmuch_database_t *db;
328    notmuch_status_t stat;
329    char *msg = NULL;
330    notmuch_message_t *message = NULL;
331    const char *id = "1258471718-6781-1-git-send-email-dottedmag@dottedmag.net";
332
333    stat = notmuch_database_open_verbose (argv[1], NOTMUCH_DATABASE_MODE_READ_WRITE, &db, &msg);
334    if (stat != NOTMUCH_STATUS_SUCCESS) {
335      fprintf (stderr, "error opening database: %d %s\n", stat, msg ? msg : "");
336      exit (1);
337    }
338    EXPECT0(notmuch_database_find_message (db, id, &message));
339    EXPECT0(notmuch_database_close (db));
340 EOF
341
342 test_begin_subtest "Handle getting message-id from closed database"
343 cat c_head2 - c_tail <<'EOF' | test_C ${MAIL_DIR}
344     {
345         const char *id2;
346         id2=notmuch_message_get_message_id (message);
347         printf("%d\n%d\n", message != NULL, id2==NULL);
348     }
349 EOF
350 cat <<EOF > EXPECTED
351 == stdout ==
352 1
353 1
354 == stderr ==
355 EOF
356 test_expect_equal_file EXPECTED OUTPUT
357
358 test_begin_subtest "Handle getting thread-id from closed database"
359 cat c_head2 - c_tail <<'EOF' | test_C ${MAIL_DIR}
360     {
361         const char *id2;
362         id2=notmuch_message_get_thread_id (message);
363         printf("%d\n%d\n", message != NULL, id2==NULL);
364     }
365 EOF
366 cat <<EOF > EXPECTED
367 == stdout ==
368 1
369 1
370 == stderr ==
371 EOF
372 test_expect_equal_file EXPECTED OUTPUT
373
374 test_begin_subtest "Handle getting header from closed database"
375 cat c_head2 - c_tail <<'EOF' | test_C ${MAIL_DIR}
376     {
377         const char *from;
378         from=notmuch_message_get_header (message, "from");
379         printf("%s\n%d\n", id, from == NULL);
380     }
381 EOF
382 cat <<EOF > EXPECTED
383 == stdout ==
384 1258471718-6781-1-git-send-email-dottedmag@dottedmag.net
385 1
386 == stderr ==
387 EOF
388 test_expect_equal_file EXPECTED OUTPUT
389
390 # XXX TODO: test on a message from notmuch_thread_get_toplevel_messages
391 # XXX this test only tests the trivial code path
392 test_begin_subtest "Handle getting replies from closed database"
393 cat c_head2 - c_tail <<'EOF' | test_C ${MAIL_DIR}
394     {
395         notmuch_messages_t *replies;
396         replies = notmuch_message_get_replies (message);
397         printf("%d\n%d\n", message != NULL, replies==NULL);
398     }
399 EOF
400 cat <<EOF > EXPECTED
401 == stdout ==
402 1
403 1
404 == stderr ==
405 EOF
406 test_expect_equal_file EXPECTED OUTPUT
407
408 test_begin_subtest "Handle getting message filename from closed database"
409 cat c_head2 - c_tail <<'EOF' | test_C ${MAIL_DIR}
410     {
411         const char *filename;
412         filename = notmuch_message_get_filename (message);
413         printf("%d\n%d\n", message != NULL, filename == NULL);
414     }
415 EOF
416 cat <<EOF > EXPECTED
417 == stdout ==
418 1
419 1
420 == stderr ==
421 EOF
422 test_expect_equal_file EXPECTED OUTPUT
423
424 test_begin_subtest "Handle getting all message filenames from closed database"
425 cat c_head2 - c_tail <<'EOF' | test_C ${MAIL_DIR}
426     {
427         notmuch_filenames_t *filenames;
428         filenames = notmuch_message_get_filenames (message);
429         printf("%d\n%d\n", message != NULL, filenames == NULL);
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_done