]> git.notmuchmail.org Git - notmuch/blob - test/T590-libconfig.sh
emacs: Add new option notmuch-search-hide-excluded
[notmuch] / test / T590-libconfig.sh
1 #!/usr/bin/env bash
2 test_description="library config API"
3
4 . $(dirname "$0")/test-lib.sh || exit 1
5
6 add_email_corpus
7
8 _libconfig_sanitize() {
9     ${NOTMUCH_PYTHON} /dev/fd/3 3<<'EOF'
10 import os, sys, pwd, socket
11
12 pw = pwd.getpwuid(os.getuid())
13 user = pw.pw_name
14 name = pw.pw_gecos.partition(",")[0]
15
16 for l in sys.stdin:
17     if l[:4] == "08: ":
18         l = l.replace(user, "USERNAME", 1)
19     elif l[:4] == "10: ":
20         l = l.replace("'" + name, "'USER_FULL_NAME", 1)
21     sys.stdout.write(l)
22 EOF
23 }
24
25 cat <<EOF > c_head
26 #include <notmuch-test.h>
27
28 int main (int argc, char** argv)
29 {
30    notmuch_database_t *db;
31    char *val;
32    notmuch_status_t stat;
33    char *msg = NULL;
34
35    for (int i = 1; i < argc; i++)
36       if (strcmp (argv[i], "%NULL%") == 0) argv[i] = NULL;
37
38    stat = notmuch_database_open_with_config (argv[1],
39                                               NOTMUCH_DATABASE_MODE_READ_WRITE,
40                                               argv[2],
41                                               argv[3],
42                                               &db,
43                                               &msg);
44    if (stat != NOTMUCH_STATUS_SUCCESS) {
45      fprintf (stderr, "error opening database\n%s\n%s\n", notmuch_status_to_string (stat), msg ? msg : "");
46      exit (1);
47    }
48 EOF
49
50 cat <<EOF > c_tail
51    EXPECT0(notmuch_database_destroy(db));
52 }
53 EOF
54
55 test_begin_subtest "notmuch_database_{set,get}_config"
56 cat c_head - c_tail <<'EOF' | test_C ${MAIL_DIR} ${NOTMUCH_CONFIG}
57 {
58    EXPECT0(notmuch_database_set_config (db, "test.key1", "testvalue1"));
59    EXPECT0(notmuch_database_set_config (db, "test.key2", "testvalue2"));
60    EXPECT0(notmuch_database_get_config (db, "test.key1", &val));
61    printf("test.key1 = %s\n", val);
62    EXPECT0(notmuch_database_get_config (db, "test.key2", &val));
63    printf("test.key2 = %s\n", val);
64 }
65 EOF
66 cat <<'EOF' >EXPECTED
67 == stdout ==
68 test.key1 = testvalue1
69 test.key2 = testvalue2
70 == stderr ==
71 EOF
72 test_expect_equal_file EXPECTED OUTPUT
73
74
75 test_begin_subtest "notmuch_database_get_config_list: empty list"
76 cat c_head - c_tail <<'EOF' | test_C ${MAIL_DIR} ${NOTMUCH_CONFIG} %NULL%
77 {
78    notmuch_config_list_t *list;
79    EXPECT0(notmuch_database_get_config_list (db, "nonexistent", &list));
80    printf("valid = %d\n", notmuch_config_list_valid (list));
81    notmuch_config_list_destroy (list);
82 }
83 EOF
84 cat <<'EOF' >EXPECTED
85 == stdout ==
86 valid = 0
87 == stderr ==
88 EOF
89 test_expect_equal_file EXPECTED OUTPUT
90
91 test_begin_subtest "notmuch_database_get_config_list: closed db"
92 cat c_head - c_tail <<'EOF' | test_C ${MAIL_DIR}
93 {
94    notmuch_config_list_t *list;
95    EXPECT0(notmuch_database_close (db));
96    stat = notmuch_database_get_config_list (db, "nonexistent", &list);
97    printf("%d\n", stat == NOTMUCH_STATUS_XAPIAN_EXCEPTION);
98 }
99 EOF
100 cat <<'EOF' >EXPECTED
101 == stdout ==
102 1
103 == stderr ==
104 EOF
105 test_expect_equal_file EXPECTED OUTPUT
106
107 test_begin_subtest "notmuch_database_get_config_list: all pairs"
108 cat c_head - c_tail <<'EOF' | test_C ${MAIL_DIR} ${NOTMUCH_CONFIG} %NULL%
109 {
110    notmuch_config_list_t *list;
111    EXPECT0(notmuch_database_set_config (db, "zzzafter", "afterval"));
112    EXPECT0(notmuch_database_set_config (db, "aaabefore", "beforeval"));
113    EXPECT0(notmuch_database_get_config_list (db, "", &list));
114    for (; notmuch_config_list_valid (list); notmuch_config_list_move_to_next (list)) {
115       printf("%s %s\n", notmuch_config_list_key (list), notmuch_config_list_value(list));
116    }
117    notmuch_config_list_destroy (list);
118 }
119 EOF
120 cat <<'EOF' >EXPECTED
121 == stdout ==
122 aaabefore beforeval
123 test.key1 testvalue1
124 test.key2 testvalue2
125 zzzafter afterval
126 == stderr ==
127 EOF
128 test_expect_equal_file EXPECTED OUTPUT
129
130 test_begin_subtest "notmuch_database_get_config_list: all pairs (closed db)"
131 cat c_head - c_tail <<'EOF' | test_C ${MAIL_DIR}
132 {
133    notmuch_config_list_t *list;
134    EXPECT0(notmuch_database_get_config_list (db, "", &list));
135    EXPECT0(notmuch_database_close (db));
136    for (; notmuch_config_list_valid (list); notmuch_config_list_move_to_next (list)) {
137       printf("%s %d\n", notmuch_config_list_key (list), NULL == notmuch_config_list_value(list));
138    }
139    notmuch_config_list_destroy (list);
140 }
141 EOF
142 cat <<'EOF' >EXPECTED
143 == stdout ==
144 aaabefore 1
145 test.key1 1
146 test.key2 1
147 zzzafter 1
148 == stderr ==
149 EOF
150 test_expect_equal_file EXPECTED OUTPUT
151
152 test_begin_subtest "notmuch_database_get_config_list: one prefix"
153 cat c_head - c_tail <<'EOF' | test_C ${MAIL_DIR} ${NOTMUCH_CONFIG} %NULL%
154 {
155    notmuch_config_list_t *list;
156    EXPECT0(notmuch_database_get_config_list (db, "test.key", &list));
157    for (; notmuch_config_list_valid (list); notmuch_config_list_move_to_next (list)) {
158       printf("%s %s\n", notmuch_config_list_key (list), notmuch_config_list_value(list));
159    }
160    notmuch_config_list_destroy (list);
161 }
162 EOF
163 cat <<'EOF' >EXPECTED
164 == stdout ==
165 test.key1 testvalue1
166 test.key2 testvalue2
167 == stderr ==
168 EOF
169 test_expect_equal_file EXPECTED OUTPUT
170
171 test_begin_subtest "dump config"
172 cat c_head - c_tail <<'EOF' | test_C ${MAIL_DIR} ${NOTMUCH_CONFIG} %NULL%
173 {
174     EXPECT0(notmuch_database_set_config (db, "key with spaces", "value, with, spaces!"));
175 }
176 EOF
177 notmuch dump --include=config >OUTPUT
178 cat <<'EOF' >EXPECTED
179 #notmuch-dump batch-tag:3 config
180 #@ aaabefore beforeval
181 #@ key%20with%20spaces value,%20with,%20spaces%21
182 #@ test.key1 testvalue1
183 #@ test.key2 testvalue2
184 #@ zzzafter afterval
185 EOF
186 test_expect_equal_file EXPECTED OUTPUT
187
188 test_begin_subtest "restore config"
189 notmuch dump --include=config >EXPECTED
190 cat c_head - c_tail <<'EOF' | test_C ${MAIL_DIR} ${NOTMUCH_CONFIG} %NULL%
191 {
192     EXPECT0(notmuch_database_set_config (db, "test.key1", "mutatedvalue"));
193 }
194 EOF
195 notmuch restore --include=config <EXPECTED
196 notmuch dump --include=config >OUTPUT
197 test_expect_equal_file EXPECTED OUTPUT
198
199 backup_database
200 test_begin_subtest "override config from file"
201 notmuch config set test.key1 overridden
202 cat c_head - c_tail <<'EOF' | test_C ${MAIL_DIR} ${NOTMUCH_CONFIG}
203 {
204    EXPECT0(notmuch_database_get_config (db, "test.key1", &val));
205    printf("test.key1 = %s\n", val);
206    EXPECT0(notmuch_database_get_config (db, "test.key2", &val));
207    printf("test.key2 = %s\n", val);
208 }
209 EOF
210 cat <<'EOF' >EXPECTED
211 == stdout ==
212 test.key1 = overridden
213 test.key2 = testvalue2
214 == stderr ==
215 EOF
216 test_expect_equal_file EXPECTED OUTPUT
217 restore_database
218
219 test_begin_subtest "NOTMUCH_CONFIG_HOOK_DIR: traditional"
220 cat c_head - c_tail <<'EOF' | test_C ${MAIL_DIR} ${NOTMUCH_CONFIG} %NULL%
221 {
222    const char *val = notmuch_config_get (db, NOTMUCH_CONFIG_HOOK_DIR);
223    printf("database.hook_dir = %s\n", val);
224 }
225 EOF
226 cat <<'EOF' >EXPECTED
227 == stdout ==
228 database.hook_dir = MAIL_DIR/.notmuch/hooks
229 == stderr ==
230 EOF
231 test_expect_equal_file EXPECTED OUTPUT
232
233 test_begin_subtest "NOTMUCH_CONFIG_HOOK_DIR: xdg"
234 dir="${HOME}/.config/notmuch/default/hooks"
235 mkdir -p $dir
236 cat c_head - c_tail <<'EOF' | test_C ${MAIL_DIR} ${NOTMUCH_CONFIG} %NULL%
237 {
238    const char *val = notmuch_config_get (db, NOTMUCH_CONFIG_HOOK_DIR);
239    printf("database.hook_dir = %s\n", val);
240 }
241 EOF
242 cat <<'EOF' >EXPECTED
243 == stdout ==
244 database.hook_dir = CWD/home/.config/notmuch/default/hooks
245 == stderr ==
246 EOF
247 rmdir $dir
248 test_expect_equal_file EXPECTED OUTPUT
249
250 test_begin_subtest "notmuch_config_get_values"
251 cat c_head - c_tail <<'EOF' | test_C ${MAIL_DIR} ${NOTMUCH_CONFIG} %NULL%
252 {
253     notmuch_config_values_t *values;
254     EXPECT0(notmuch_config_set (db, NOTMUCH_CONFIG_NEW_TAGS, "a;b;c"));
255     for (values = notmuch_config_get_values (db, NOTMUCH_CONFIG_NEW_TAGS);
256          notmuch_config_values_valid (values);
257          notmuch_config_values_move_to_next (values))
258     {
259           puts (notmuch_config_values_get (values));
260     }
261 }
262 EOF
263 cat <<'EOF' >EXPECTED
264 == stdout ==
265 a
266 b
267 c
268 == stderr ==
269 EOF
270 test_expect_equal_file EXPECTED OUTPUT
271 restore_database
272
273 test_begin_subtest "notmuch_config_get_values (ignore leading/trailing whitespace)"
274 cat c_head - c_tail <<'EOF' | test_C ${MAIL_DIR} ${NOTMUCH_CONFIG} %NULL%
275 {
276     notmuch_config_values_t *values;
277     EXPECT0(notmuch_config_set (db, NOTMUCH_CONFIG_NEW_TAGS, " a ; b c ; d "));
278     for (values = notmuch_config_get_values (db, NOTMUCH_CONFIG_NEW_TAGS);
279          notmuch_config_values_valid (values);
280          notmuch_config_values_move_to_next (values))
281     {
282           puts (notmuch_config_values_get (values));
283     }
284 }
285 EOF
286 cat <<'EOF' >EXPECTED
287 == stdout ==
288 a
289 b c
290 d
291 == stderr ==
292 EOF
293 test_expect_equal_file EXPECTED OUTPUT
294 restore_database
295
296 test_begin_subtest "notmuch_config_get_values_string"
297 cat c_head - c_tail <<'EOF' | test_C ${MAIL_DIR} ${NOTMUCH_CONFIG} %NULL%
298 {
299     notmuch_config_values_t *values;
300     EXPECT0(notmuch_database_set_config (db, "test.list", "x;y;z"));
301     for (values = notmuch_config_get_values_string (db, "test.list");
302          notmuch_config_values_valid (values);
303          notmuch_config_values_move_to_next (values))
304     {
305           puts (notmuch_config_values_get (values));
306     }
307 }
308 EOF
309 cat <<'EOF' >EXPECTED
310 == stdout ==
311 x
312 y
313 z
314 == stderr ==
315 EOF
316 test_expect_equal_file EXPECTED OUTPUT
317 restore_database
318
319 test_begin_subtest "notmuch_config_get_values (restart)"
320 cat c_head - c_tail <<'EOF' | test_C ${MAIL_DIR} ${NOTMUCH_CONFIG} %NULL%
321 {
322     notmuch_config_values_t *values;
323     EXPECT0(notmuch_config_set (db, NOTMUCH_CONFIG_NEW_TAGS, "a;b;c"));
324     for (values = notmuch_config_get_values (db, NOTMUCH_CONFIG_NEW_TAGS);
325          notmuch_config_values_valid (values);
326          notmuch_config_values_move_to_next (values))
327     {
328           puts (notmuch_config_values_get (values));
329     }
330     for (notmuch_config_values_start (values);
331          notmuch_config_values_valid (values);
332          notmuch_config_values_move_to_next (values))
333     {
334           puts (notmuch_config_values_get (values));
335     }
336 }
337 EOF
338 cat <<'EOF' >EXPECTED
339 == stdout ==
340 a
341 b
342 c
343 a
344 b
345 c
346 == stderr ==
347 EOF
348 test_expect_equal_file EXPECTED OUTPUT
349 restore_database
350
351 backup_database
352 test_begin_subtest "notmuch_config_get_values, trailing ;"
353 cat c_head - c_tail <<'EOF' | test_C ${MAIL_DIR} ${NOTMUCH_CONFIG} %NULL%
354 {
355     notmuch_config_values_t *values;
356     EXPECT0(notmuch_config_set (db, NOTMUCH_CONFIG_NEW_TAGS, "a;b;c"));
357     for (values = notmuch_config_get_values (db, NOTMUCH_CONFIG_NEW_TAGS);
358          notmuch_config_values_valid (values);
359          notmuch_config_values_move_to_next (values))
360     {
361           puts (notmuch_config_values_get (values));
362     }
363 }
364 EOF
365 cat <<'EOF' >EXPECTED
366 == stdout ==
367 a
368 b
369 c
370 == stderr ==
371 EOF
372 test_expect_equal_file EXPECTED OUTPUT
373 restore_database
374
375 backup_database
376 test_begin_subtest "get config by key"
377 cat c_head - c_tail <<'EOF' | test_C ${MAIL_DIR} ${NOTMUCH_CONFIG}
378 {
379    printf("before = %s\n", notmuch_config_get (db, NOTMUCH_CONFIG_SYNC_MAILDIR_FLAGS));
380    EXPECT0(notmuch_database_set_config (db, "maildir.synchronize_flags", "false"));
381    printf("after = %s\n", notmuch_config_get (db, NOTMUCH_CONFIG_SYNC_MAILDIR_FLAGS));
382 }
383 EOF
384 cat <<'EOF' >EXPECTED
385 == stdout ==
386 before = true
387 after = false
388 == stderr ==
389 EOF
390 test_expect_equal_file EXPECTED OUTPUT
391 restore_database
392
393 backup_database
394 test_begin_subtest "set config by key"
395 notmuch config set test.key1 overridden
396 cat c_head - c_tail <<'EOF' | test_C ${MAIL_DIR} ${NOTMUCH_CONFIG}
397 {
398    printf("before = %s\n", notmuch_config_get (db, NOTMUCH_CONFIG_SYNC_MAILDIR_FLAGS));
399    EXPECT0(notmuch_config_set (db, NOTMUCH_CONFIG_SYNC_MAILDIR_FLAGS, "false"));
400    printf("after = %s\n", notmuch_config_get (db, NOTMUCH_CONFIG_SYNC_MAILDIR_FLAGS));
401 }
402 EOF
403 cat <<'EOF' >EXPECTED
404 == stdout ==
405 before = true
406 after = false
407 == stderr ==
408 EOF
409 test_expect_equal_file EXPECTED OUTPUT
410 restore_database
411
412 test_begin_subtest "load default values"
413 export MAILDIR=${MAIL_DIR}
414 cat c_head - c_tail <<'EOF' | test_C ${MAIL_DIR} '' %NULL%
415 {
416     notmuch_config_key_t key;
417     for (key = NOTMUCH_CONFIG_FIRST;
418          key < NOTMUCH_CONFIG_LAST;
419          key = (notmuch_config_key_t)(key + 1)) {
420         const char *val = notmuch_config_get (db, key);
421         printf("%02d: '%s'\n", key, val ? val : "NULL" );
422     }
423 }
424 EOF
425
426 _libconfig_sanitize < OUTPUT > OUTPUT.clean
427
428 cat <<'EOF' >EXPECTED
429 == stdout ==
430 00: 'MAIL_DIR'
431 01: 'MAIL_DIR'
432 02: 'MAIL_DIR/.notmuch/hooks'
433 03: 'MAIL_DIR/.notmuch/backups'
434 04: ''
435 05: 'unread;inbox'
436 06: ''
437 07: 'true'
438 08: 'USERNAME@localhost'
439 09: 'NULL'
440 10: 'USER_FULL_NAME'
441 11: '8000'
442 12: 'NULL'
443 13: ''
444 == stderr ==
445 EOF
446 unset MAILDIR
447 test_expect_equal_file EXPECTED OUTPUT.clean
448
449 backup_database
450 test_begin_subtest "override config from \${NOTMUCH_CONFIG}"
451 notmuch config set test.key1 overridden
452 # second argument omitted to make argv[2] == NULL
453 cat c_head - c_tail <<'EOF' | test_C ${MAIL_DIR}
454 {
455    EXPECT0(notmuch_database_get_config (db, "test.key1", &val));
456    printf("test.key1 = %s\n", val);
457    EXPECT0(notmuch_database_get_config (db, "test.key2", &val));
458    printf("test.key2 = %s\n", val);
459 }
460 EOF
461 notmuch config set test.key1
462 cat <<'EOF' >EXPECTED
463 == stdout ==
464 test.key1 = overridden
465 test.key2 = testvalue2
466 == stderr ==
467 EOF
468 test_expect_equal_file EXPECTED OUTPUT
469 restore_database
470
471 backup_database
472 test_begin_subtest "override config from \${HOME}/.notmuch-config"
473 ovconfig=${HOME}/.notmuch-config
474 cp ${NOTMUCH_CONFIG} ${ovconfig}
475 old_NOTMUCH_CONFIG=${NOTMUCH_CONFIG}
476 unset NOTMUCH_CONFIG
477 notmuch --config=${ovconfig} config set test.key1 overridden-home
478 cat c_head - c_tail <<'EOF' | test_C ${MAIL_DIR} %NULL% %NULL%
479 {
480    EXPECT0(notmuch_database_get_config (db, "test.key1", &val));
481    printf("test.key1 = %s\n", val);
482    EXPECT0(notmuch_database_get_config (db, "test.key2", &val));
483    printf("test.key2 = %s\n", val);
484 }
485 EOF
486 rm -f ${ovconfig}
487 export NOTMUCH_CONFIG=${old_NOTMUCH_CONFIG}
488 cat <<'EOF' >EXPECTED
489 == stdout ==
490 test.key1 = overridden-home
491 test.key2 = testvalue2
492 == stderr ==
493 EOF
494 test_expect_equal_file EXPECTED OUTPUT
495 restore_database
496
497 backup_database
498 test_begin_subtest "override config from \${XDG_CONFIG_HOME}/notmuch"
499 ovconfig=${HOME}/.config/notmuch/default/config
500 mkdir -p $(dirname ${ovconfig})
501 cp ${NOTMUCH_CONFIG} ${ovconfig}
502 old_NOTMUCH_CONFIG=${NOTMUCH_CONFIG}
503 unset NOTMUCH_CONFIG
504 notmuch --config=${ovconfig} config set test.key1 overridden-xdg
505 cat c_head - c_tail <<'EOF' | test_C ${MAIL_DIR} %NULL% %NULL%
506 {
507    EXPECT0(notmuch_database_get_config (db, "test.key1", &val));
508    printf("test.key1 = %s\n", val);
509    EXPECT0(notmuch_database_get_config (db, "test.key2", &val));
510    printf("test.key2 = %s\n", val);
511 }
512 EOF
513 rm -f ${ovconfig}
514 export NOTMUCH_CONFIG=${old_NOTMUCH_CONFIG}
515 cat <<'EOF' >EXPECTED
516 == stdout ==
517 test.key1 = overridden-xdg
518 test.key2 = testvalue2
519 == stderr ==
520 EOF
521 test_expect_equal_file EXPECTED OUTPUT
522 restore_database
523
524 backup_database
525 test_begin_subtest "override config from \${XDG_CONFIG_HOME}/notmuch with profile"
526 ovconfig=${HOME}/.config/notmuch/work/config
527 mkdir -p $(dirname ${ovconfig})
528 cp ${NOTMUCH_CONFIG} ${ovconfig}
529 old_NOTMUCH_CONFIG=${NOTMUCH_CONFIG}
530 unset NOTMUCH_CONFIG
531 notmuch --config=${ovconfig} config set test.key1 overridden-xdg-profile
532 cat c_head - c_tail <<'EOF' | test_C ${MAIL_DIR} %NULL% work
533 {
534    EXPECT0(notmuch_database_get_config (db, "test.key1", &val));
535    printf("test.key1 = %s\n", val);
536    EXPECT0(notmuch_database_get_config (db, "test.key2", &val));
537    printf("test.key2 = %s\n", val);
538 }
539 EOF
540 rm -f ${ovconfig}
541 export NOTMUCH_CONFIG=${old_NOTMUCH_CONFIG}
542 cat <<'EOF' >EXPECTED
543 == stdout ==
544 test.key1 = overridden-xdg-profile
545 test.key2 = testvalue2
546 == stderr ==
547 EOF
548 test_expect_equal_file EXPECTED OUTPUT
549 restore_database
550
551 backup_database
552 test_begin_subtest "override config from \${HOME}/.notmuch-config.work (via args)"
553 ovconfig=${HOME}/.notmuch-config.work
554 cp ${NOTMUCH_CONFIG} ${ovconfig}
555 old_NOTMUCH_CONFIG=${NOTMUCH_CONFIG}
556 unset NOTMUCH_CONFIG
557 notmuch --config=${ovconfig} config set test.key1 overridden-profile
558 cat c_head - c_tail <<'EOF' | test_C ${MAIL_DIR} %NULL% work
559 {
560    EXPECT0(notmuch_database_get_config (db, "test.key1", &val));
561    printf("test.key1 = %s\n", val);
562    EXPECT0(notmuch_database_get_config (db, "test.key2", &val));
563    printf("test.key2 = %s\n", val);
564 }
565 EOF
566 #rm -f ${ovconfig}
567 export NOTMUCH_CONFIG=${old_NOTMUCH_CONFIG}
568 cat <<'EOF' >EXPECTED
569 == stdout ==
570 test.key1 = overridden-profile
571 test.key2 = testvalue2
572 == stderr ==
573 EOF
574 test_expect_equal_file EXPECTED OUTPUT
575 restore_database
576
577 test_begin_subtest "no config, fail to open database"
578 old_NOTMUCH_CONFIG=${NOTMUCH_CONFIG}
579 unset NOTMUCH_CONFIG
580 cat c_head - c_tail <<'EOF' | test_C %NULL% '' %NULL%
581 {
582    printf("NOT RUN");
583 }
584 EOF
585 export NOTMUCH_CONFIG=${old_NOTMUCH_CONFIG}
586 cat <<'EOF' >EXPECTED
587 == stdout ==
588 == stderr ==
589 error opening database
590 No database found
591 Error: could not locate database.
592
593 EOF
594 test_expect_equal_file EXPECTED OUTPUT
595
596 test_begin_subtest "open database from NOTMUCH_DATABASE"
597 old_NOTMUCH_CONFIG=${NOTMUCH_CONFIG}
598 unset NOTMUCH_CONFIG
599 export NOTMUCH_DATABASE=${MAIL_DIR}
600 cat c_head - c_tail <<'EOF' | test_C %NULL% '' %NULL%
601 {
602    EXPECT0(notmuch_database_get_config (db, "test.key1", &val));
603    printf("test.key1 = %s\n", val);
604    EXPECT0(notmuch_database_get_config (db, "test.key2", &val));
605    printf("test.key2 = %s\n", val);
606 }
607 EOF
608 export NOTMUCH_CONFIG=${old_NOTMUCH_CONFIG}
609 unset NOTMUCH_DATABASE
610 cat <<'EOF' >EXPECTED
611 == stdout ==
612 test.key1 = testvalue1
613 test.key2 = testvalue2
614 == stderr ==
615 EOF
616 test_expect_equal_file EXPECTED OUTPUT
617
618 test_begin_subtest "NOTMUCH_DATABASE overrides config"
619 cp notmuch-config notmuch-config.bak
620 notmuch config set database.path /nonexistent
621 export NOTMUCH_DATABASE=${MAIL_DIR}
622 cat c_head - c_tail <<'EOF' | test_C %NULL% '' %NULL%
623 {
624    EXPECT0(notmuch_database_get_config (db, "test.key1", &val));
625    printf("test.key1 = %s\n", val);
626    EXPECT0(notmuch_database_get_config (db, "test.key2", &val));
627    printf("test.key2 = %s\n", val);
628 }
629 EOF
630 export NOTMUCH_CONFIG=${old_NOTMUCH_CONFIG}
631 unset NOTMUCH_DATABASE
632 cat <<'EOF' >EXPECTED
633 == stdout ==
634 test.key1 = testvalue1
635 test.key2 = testvalue2
636 == stderr ==
637 EOF
638 cp notmuch-config.bak notmuch-config
639 test_expect_equal_file EXPECTED OUTPUT
640
641 cat <<EOF > c_head2
642 #include <notmuch-test.h>
643
644 int main (int argc, char** argv)
645 {
646    notmuch_database_t *db;
647    char *val;
648    notmuch_status_t stat;
649    char *msg = NULL;
650
651    for (int i = 1; i < argc; i++)
652       if (strcmp (argv[i], "%NULL%") == 0) argv[i] = NULL;
653
654    stat = notmuch_database_load_config (argv[1],
655                                         argv[2],
656                                         argv[3],
657                                         &db,
658                                         &msg);
659    if (stat != NOTMUCH_STATUS_SUCCESS  && stat != NOTMUCH_STATUS_NO_CONFIG) {
660      fprintf (stderr, "error opening database\n%d: %s\n%s\n", stat,
661               notmuch_status_to_string (stat), msg ? msg : "");
662      exit (1);
663    }
664 EOF
665
666
667 test_begin_subtest "notmuch_database_get_config (ndlc)"
668 cat c_head2 - c_tail <<'EOF' | test_C ${MAIL_DIR} %NULL% %NULL%
669 {
670    EXPECT0(notmuch_database_get_config (db, "test.key1", &val));
671    printf("test.key1 = %s\n", val);
672    EXPECT0(notmuch_database_get_config (db, "test.key2", &val));
673    printf("test.key2 = %s\n", val);
674 }
675 EOF
676 cat <<'EOF' >EXPECTED
677 == stdout ==
678 test.key1 = testvalue1
679 test.key2 = testvalue2
680 == stderr ==
681 EOF
682 test_expect_equal_file EXPECTED OUTPUT
683
684
685 test_begin_subtest "notmuch_database_get_config_list: all pairs (ndlc)"
686 cat c_head2 - c_tail <<'EOF' | test_C ${MAIL_DIR} ${NOTMUCH_CONFIG} %NULL%
687 {
688    notmuch_config_list_t *list;
689    EXPECT0(notmuch_database_get_config_list (db, "", &list));
690    for (; notmuch_config_list_valid (list); notmuch_config_list_move_to_next (list)) {
691       printf("%s %s\n", notmuch_config_list_key (list), notmuch_config_list_value(list));
692    }
693    notmuch_config_list_destroy (list);
694 }
695 EOF
696 cat <<'EOF' >EXPECTED
697 == stdout ==
698 aaabefore beforeval
699 key with spaces value, with, spaces!
700 test.key1 testvalue1
701 test.key2 testvalue2
702 zzzafter afterval
703 == stderr ==
704 EOF
705 test_expect_equal_file EXPECTED OUTPUT
706
707 test_begin_subtest "notmuch_database_get_config_list: one prefix (ndlc)"
708 cat c_head2 - c_tail <<'EOF' | test_C ${MAIL_DIR} ${NOTMUCH_CONFIG} %NULL%
709 {
710    notmuch_config_list_t *list;
711    EXPECT0(notmuch_database_get_config_list (db, "test.key", &list));
712    for (; notmuch_config_list_valid (list); notmuch_config_list_move_to_next (list)) {
713       printf("%s %s\n", notmuch_config_list_key (list), notmuch_config_list_value(list));
714    }
715    notmuch_config_list_destroy (list);
716 }
717 EOF
718 cat <<'EOF' >EXPECTED
719 == stdout ==
720 test.key1 testvalue1
721 test.key2 testvalue2
722 == stderr ==
723 EOF
724 test_expect_equal_file EXPECTED OUTPUT
725
726 test_begin_subtest "list by keys (ndlc)"
727 notmuch config set search.exclude_tags "foo;bar;fub"
728 notmuch config set new.ignore "sekrit_junk"
729 notmuch config set index.as_text "text/"
730 cat c_head2 - c_tail <<'EOF' | test_C ${MAIL_DIR} %NULL% %NULL%
731 {
732     notmuch_config_key_t key;
733     for (key = NOTMUCH_CONFIG_FIRST;
734          key < NOTMUCH_CONFIG_LAST;
735          key = (notmuch_config_key_t)(key + 1)) {
736         const char *val = notmuch_config_get (db, key);
737         printf("%02d: '%s'\n", key, val ? val : "NULL" );
738     }
739 }
740 EOF
741 cat <<'EOF' >EXPECTED
742 == stdout ==
743 00: 'MAIL_DIR'
744 01: 'MAIL_DIR'
745 02: 'MAIL_DIR/.notmuch/hooks'
746 03: 'MAIL_DIR/.notmuch/backups'
747 04: 'foo;bar;fub'
748 05: 'unread;inbox'
749 06: 'sekrit_junk'
750 07: 'true'
751 08: 'test_suite@notmuchmail.org'
752 09: 'test_suite_other@notmuchmail.org;test_suite@otherdomain.org'
753 10: 'Notmuch Test Suite'
754 11: '8000'
755 12: 'NULL'
756 13: 'text/'
757 == stderr ==
758 EOF
759 test_expect_equal_file EXPECTED OUTPUT
760
761 test_begin_subtest "load default values (ndlc, nonexistent config)"
762 cat c_head2 - c_tail <<'EOF' | test_C ${MAIL_DIR} /nonexistent %NULL%
763 {
764     notmuch_config_key_t key;
765     for (key = NOTMUCH_CONFIG_FIRST;
766          key < NOTMUCH_CONFIG_LAST;
767          key = (notmuch_config_key_t)(key + 1)) {
768         const char *val = notmuch_config_get (db, key);
769         printf("%02d: '%s'\n", key, val ? val : "NULL" );
770     }
771 }
772 EOF
773
774 _libconfig_sanitize < OUTPUT > OUTPUT.clean
775
776 cat <<'EOF' >EXPECTED
777 == stdout ==
778 00: 'MAIL_DIR'
779 01: 'MAIL_DIR'
780 02: 'MAIL_DIR/.notmuch/hooks'
781 03: 'MAIL_DIR/.notmuch/backups'
782 04: ''
783 05: 'unread;inbox'
784 06: ''
785 07: 'true'
786 08: 'USERNAME@localhost'
787 09: 'NULL'
788 10: 'USER_FULL_NAME'
789 11: '8000'
790 12: 'NULL'
791 13: ''
792 == stderr ==
793 EOF
794 test_expect_equal_file EXPECTED OUTPUT.clean
795
796 backup_database
797 test_begin_subtest "override config from \${HOME}/.notmuch-config (ndlc)"
798 ovconfig=${HOME}/.notmuch-config
799 cp ${NOTMUCH_CONFIG} ${ovconfig}
800 old_NOTMUCH_CONFIG=${NOTMUCH_CONFIG}
801 unset NOTMUCH_CONFIG
802 notmuch --config=${ovconfig} config set test.key1 overridden-home
803 cat c_head2 - c_tail <<'EOF' | test_C ${MAIL_DIR} %NULL% %NULL%
804 {
805    EXPECT0(notmuch_database_get_config (db, "test.key1", &val));
806    printf("test.key1 = %s\n", val);
807    EXPECT0(notmuch_database_get_config (db, "test.key2", &val));
808    printf("test.key2 = %s\n", val);
809 }
810 EOF
811 rm -f ${ovconfig}
812 export NOTMUCH_CONFIG=${old_NOTMUCH_CONFIG}
813 cat <<'EOF' >EXPECTED
814 == stdout ==
815 test.key1 = overridden-home
816 test.key2 = testvalue2
817 == stderr ==
818 EOF
819 test_expect_equal_file EXPECTED OUTPUT
820 restore_database
821
822 test_begin_subtest "notmuch_config_get_pairs: prefix (ndlc)"
823 cat c_head2 - c_tail <<'EOF' | test_C ${MAIL_DIR} ${NOTMUCH_CONFIG} %NULL%
824 {
825    notmuch_config_pairs_t *list;
826    for (list =  notmuch_config_get_pairs (db, "user.");
827         notmuch_config_pairs_valid (list);
828         notmuch_config_pairs_move_to_next (list)) {
829      printf("%s %s\n", notmuch_config_pairs_key (list), notmuch_config_pairs_value(list));
830    }
831    notmuch_config_pairs_destroy (list);
832 }
833 EOF
834 cat <<'EOF' >EXPECTED
835 == stdout ==
836 user.name Notmuch Test Suite
837 user.other_email test_suite_other@notmuchmail.org;test_suite@otherdomain.org
838 user.primary_email test_suite@notmuchmail.org
839 == stderr ==
840 EOF
841 test_expect_equal_file EXPECTED OUTPUT
842
843 test_begin_subtest "notmuch_config_get_pairs: all pairs (ndlc)"
844 cat c_head2 - c_tail <<'EOF' | test_C ${MAIL_DIR} ${NOTMUCH_CONFIG} %NULL%
845 {
846    notmuch_config_pairs_t *list;
847    for (list =  notmuch_config_get_pairs (db, "");
848         notmuch_config_pairs_valid (list);
849         notmuch_config_pairs_move_to_next (list)) {
850      printf("%s %s\n", notmuch_config_pairs_key (list), notmuch_config_pairs_value(list));
851    }
852    notmuch_config_pairs_destroy (list);
853 }
854 EOF
855 cat <<'EOF' >EXPECTED
856 == stdout ==
857 aaabefore beforeval
858 database.autocommit 8000
859 database.backup_dir MAIL_DIR/.notmuch/backups
860 database.hook_dir MAIL_DIR/.notmuch/hooks
861 database.mail_root MAIL_DIR
862 database.path MAIL_DIR
863 index.as_text text/
864 key with spaces value, with, spaces!
865 maildir.synchronize_flags true
866 new.ignore sekrit_junk
867 new.tags unread;inbox
868 search.exclude_tags foo;bar;fub
869 show.extra_headers (null)
870 test.key1 testvalue1
871 test.key2 testvalue2
872 user.name Notmuch Test Suite
873 user.other_email test_suite_other@notmuchmail.org;test_suite@otherdomain.org
874 user.primary_email test_suite@notmuchmail.org
875 zzzafter afterval
876 == stderr ==
877 EOF
878 test_expect_equal_file EXPECTED OUTPUT
879
880 cat <<EOF > c_head3
881 #include <notmuch-test.h>
882 int main (int argc, char **argv) {
883   notmuch_status_t stat;
884   notmuch_database_t *db = NULL;
885 EOF
886
887 cat <<EOF > c_tail3
888   printf("db == NULL: %d\n", db == NULL);
889 }
890 EOF
891
892 test_begin_subtest "open: database set to null on missing config"
893 cat c_head3 - c_tail3 <<'EOF' | test_C ${MAIL_DIR}
894   notmuch_status_t st = notmuch_database_open_with_config(argv[1],
895                                                           NOTMUCH_DATABASE_MODE_READ_ONLY,
896                                                           "/nonexistent", NULL, &db, NULL);
897 EOF
898 cat <<EOF> EXPECTED
899 == stdout ==
900 db == NULL: 1
901 == stderr ==
902 EOF
903 test_expect_equal_file EXPECTED OUTPUT
904
905 test_begin_subtest "open: database set to null on missing config (env)"
906 old_NOTMUCH_CONFIG=${NOTMUCH_CONFIG}
907 export NOTMUCH_CONFIG="/nonexistent"
908 cat c_head3 - c_tail3 <<'EOF' | test_C ${MAIL_DIR}
909   notmuch_status_t st = notmuch_database_open_with_config(argv[1],
910                                                           NOTMUCH_DATABASE_MODE_READ_ONLY,
911                                                           NULL, NULL, &db, NULL);
912 EOF
913 export NOTMUCH_CONFIG=${old_NOTMUCH_CONFIG}
914 cat <<EOF> EXPECTED
915 == stdout ==
916 db == NULL: 1
917 == stderr ==
918 EOF
919 test_expect_equal_file EXPECTED OUTPUT
920
921 test_begin_subtest "create: database set to null on missing config"
922 cat c_head3 - c_tail3 <<'EOF' | test_C ${MAIL_DIR} "/nonexistent"
923   notmuch_status_t st = notmuch_database_create_with_config(argv[1],argv[2], NULL, &db, NULL);
924 EOF
925 cat <<EOF> EXPECTED
926 == stdout ==
927 db == NULL: 1
928 == stderr ==
929 EOF
930 test_expect_equal_file EXPECTED OUTPUT
931
932 test_begin_subtest "create: database set to null on missing config (env)"
933 old_NOTMUCH_CONFIG=${NOTMUCH_CONFIG}
934 export NOTMUCH_CONFIG="/nonexistent"
935 cat c_head3 - c_tail3 <<'EOF' | test_C ${MAIL_DIR}
936   notmuch_status_t st = notmuch_database_create_with_config(argv[1],
937                                                           NULL, NULL, &db, NULL);
938 EOF
939 export NOTMUCH_CONFIG=${old_NOTMUCH_CONFIG}
940 cat <<EOF> EXPECTED
941 == stdout ==
942 db == NULL: 1
943 == stderr ==
944 EOF
945 test_expect_equal_file EXPECTED OUTPUT
946
947 test_begin_subtest "load_config: database set non-null on missing config"
948 cat c_head3 - c_tail3 <<'EOF' | test_C ${MAIL_DIR} "/nonexistent"
949   notmuch_status_t st = notmuch_database_load_config(argv[1],argv[2], NULL, &db, NULL);
950 EOF
951 cat <<EOF> EXPECTED
952 == stdout ==
953 db == NULL: 0
954 == stderr ==
955 EOF
956 test_expect_equal_file EXPECTED OUTPUT
957
958 test_begin_subtest "load_config: database non-null on missing config (env)"
959 old_NOTMUCH_CONFIG=${NOTMUCH_CONFIG}
960 export NOTMUCH_CONFIG="/nonexistent"
961 cat c_head3 - c_tail3 <<'EOF' | test_C ${MAIL_DIR}
962   notmuch_status_t st = notmuch_database_load_config(argv[1], NULL, NULL, &db, NULL);
963 EOF
964 export NOTMUCH_CONFIG=${old_NOTMUCH_CONFIG}
965 cat <<EOF> EXPECTED
966 == stdout ==
967 db == NULL: 0
968 == stderr ==
969 EOF
970 test_expect_equal_file EXPECTED OUTPUT
971
972 test_begin_subtest "load_config: database set to NULL on fatal error"
973 cat c_head3 - c_tail3 <<'EOF' | test_C
974   notmuch_status_t st = notmuch_database_load_config("relative", NULL, NULL, &db, NULL);
975 EOF
976 cat <<EOF> EXPECTED
977 == stdout ==
978 db == NULL: 1
979 == stderr ==
980 EOF
981 test_expect_equal_file EXPECTED OUTPUT
982
983 test_begin_subtest "open: database parameter overrides implicit config"
984 cp $NOTMUCH_CONFIG ${NOTMUCH_CONFIG}.bak
985 notmuch config set database.path ${MAIL_DIR}/nonexistent
986 cat c_head3 - c_tail3 <<'EOF' | test_C ${MAIL_DIR}
987   const char *path = NULL;
988   notmuch_status_t st = notmuch_database_open_with_config(argv[1],
989                                                           NOTMUCH_DATABASE_MODE_READ_ONLY,
990                                                           NULL, NULL, &db, NULL);
991   printf ("status: %d\n", st);
992   path = notmuch_database_get_path (db);
993   printf ("path: %s\n", path ? path : "(null)");
994 EOF
995 cp ${NOTMUCH_CONFIG}.bak ${NOTMUCH_CONFIG}
996 cat <<EOF> EXPECTED
997 == stdout ==
998 status: 0
999 path: MAIL_DIR
1000 db == NULL: 0
1001 == stderr ==
1002 EOF
1003 notmuch_dir_sanitize < OUTPUT > OUTPUT.clean
1004 test_expect_equal_file EXPECTED OUTPUT.clean
1005
1006 cat <<EOF > c_body
1007   notmuch_status_t st = notmuch_database_open_with_config(NULL,
1008                                                           NOTMUCH_DATABASE_MODE_READ_ONLY,
1009                                                           "", NULL, &db, NULL);
1010   printf ("status == SUCCESS: %d\n", st == NOTMUCH_STATUS_SUCCESS);
1011   if (db) {
1012     const char *mail_root = NULL;
1013     mail_root = notmuch_config_get (db, NOTMUCH_CONFIG_MAIL_ROOT);
1014     printf ("mail_root: %s\n", mail_root ? mail_root : "(null)");
1015   }
1016 EOF
1017
1018 cat <<EOF> EXPECTED.common
1019 == stdout ==
1020 status == SUCCESS: 0
1021 db == NULL: 1
1022 == stderr ==
1023 EOF
1024
1025 test_begin_subtest "open/error: config=empty with no mail root in db "
1026 old_NOTMUCH_CONFIG=${NOTMUCH_CONFIG}
1027 unset NOTMUCH_CONFIG
1028 cat c_head3 c_body c_tail3 | test_C
1029 export NOTMUCH_CONFIG=${old_NOTMUCH_CONFIG}
1030 notmuch_dir_sanitize < OUTPUT > OUTPUT.clean
1031 test_expect_equal_file EXPECTED.common OUTPUT.clean
1032
1033 test_begin_subtest "open/error: config=empty with no mail root in db (xdg)"
1034 old_NOTMUCH_CONFIG=${NOTMUCH_CONFIG}
1035 unset NOTMUCH_CONFIG
1036 backup_database
1037 mkdir -p home/.local/share/notmuch
1038 mv mail/.notmuch home/.local/share/notmuch/default
1039 cat c_head3 c_body c_tail3 | test_C
1040 restore_database
1041 export NOTMUCH_CONFIG=${old_NOTMUCH_CONFIG}
1042 notmuch_dir_sanitize < OUTPUT > OUTPUT.clean
1043 test_expect_equal_file EXPECTED.common OUTPUT.clean
1044
1045 test_done