]> 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 == stderr ==
444 EOF
445 unset MAILDIR
446 test_expect_equal_file EXPECTED OUTPUT.clean
447
448 backup_database
449 test_begin_subtest "override config from \${NOTMUCH_CONFIG}"
450 notmuch config set test.key1 overridden
451 # second argument omitted to make argv[2] == NULL
452 cat c_head - c_tail <<'EOF' | test_C ${MAIL_DIR}
453 {
454    EXPECT0(notmuch_database_get_config (db, "test.key1", &val));
455    printf("test.key1 = %s\n", val);
456    EXPECT0(notmuch_database_get_config (db, "test.key2", &val));
457    printf("test.key2 = %s\n", val);
458 }
459 EOF
460 notmuch config set test.key1
461 cat <<'EOF' >EXPECTED
462 == stdout ==
463 test.key1 = overridden
464 test.key2 = testvalue2
465 == stderr ==
466 EOF
467 test_expect_equal_file EXPECTED OUTPUT
468 restore_database
469
470 backup_database
471 test_begin_subtest "override config from \${HOME}/.notmuch-config"
472 ovconfig=${HOME}/.notmuch-config
473 cp ${NOTMUCH_CONFIG} ${ovconfig}
474 old_NOTMUCH_CONFIG=${NOTMUCH_CONFIG}
475 unset NOTMUCH_CONFIG
476 notmuch --config=${ovconfig} config set test.key1 overridden-home
477 cat c_head - c_tail <<'EOF' | test_C ${MAIL_DIR} %NULL% %NULL%
478 {
479    EXPECT0(notmuch_database_get_config (db, "test.key1", &val));
480    printf("test.key1 = %s\n", val);
481    EXPECT0(notmuch_database_get_config (db, "test.key2", &val));
482    printf("test.key2 = %s\n", val);
483 }
484 EOF
485 rm -f ${ovconfig}
486 export NOTMUCH_CONFIG=${old_NOTMUCH_CONFIG}
487 cat <<'EOF' >EXPECTED
488 == stdout ==
489 test.key1 = overridden-home
490 test.key2 = testvalue2
491 == stderr ==
492 EOF
493 test_expect_equal_file EXPECTED OUTPUT
494 restore_database
495
496 backup_database
497 test_begin_subtest "override config from \${XDG_CONFIG_HOME}/notmuch"
498 ovconfig=${HOME}/.config/notmuch/default/config
499 mkdir -p $(dirname ${ovconfig})
500 cp ${NOTMUCH_CONFIG} ${ovconfig}
501 old_NOTMUCH_CONFIG=${NOTMUCH_CONFIG}
502 unset NOTMUCH_CONFIG
503 notmuch --config=${ovconfig} config set test.key1 overridden-xdg
504 cat c_head - c_tail <<'EOF' | test_C ${MAIL_DIR} %NULL% %NULL%
505 {
506    EXPECT0(notmuch_database_get_config (db, "test.key1", &val));
507    printf("test.key1 = %s\n", val);
508    EXPECT0(notmuch_database_get_config (db, "test.key2", &val));
509    printf("test.key2 = %s\n", val);
510 }
511 EOF
512 rm -f ${ovconfig}
513 export NOTMUCH_CONFIG=${old_NOTMUCH_CONFIG}
514 cat <<'EOF' >EXPECTED
515 == stdout ==
516 test.key1 = overridden-xdg
517 test.key2 = testvalue2
518 == stderr ==
519 EOF
520 test_expect_equal_file EXPECTED OUTPUT
521 restore_database
522
523 backup_database
524 test_begin_subtest "override config from \${XDG_CONFIG_HOME}/notmuch with profile"
525 ovconfig=${HOME}/.config/notmuch/work/config
526 mkdir -p $(dirname ${ovconfig})
527 cp ${NOTMUCH_CONFIG} ${ovconfig}
528 old_NOTMUCH_CONFIG=${NOTMUCH_CONFIG}
529 unset NOTMUCH_CONFIG
530 notmuch --config=${ovconfig} config set test.key1 overridden-xdg-profile
531 cat c_head - c_tail <<'EOF' | test_C ${MAIL_DIR} %NULL% work
532 {
533    EXPECT0(notmuch_database_get_config (db, "test.key1", &val));
534    printf("test.key1 = %s\n", val);
535    EXPECT0(notmuch_database_get_config (db, "test.key2", &val));
536    printf("test.key2 = %s\n", val);
537 }
538 EOF
539 rm -f ${ovconfig}
540 export NOTMUCH_CONFIG=${old_NOTMUCH_CONFIG}
541 cat <<'EOF' >EXPECTED
542 == stdout ==
543 test.key1 = overridden-xdg-profile
544 test.key2 = testvalue2
545 == stderr ==
546 EOF
547 test_expect_equal_file EXPECTED OUTPUT
548 restore_database
549
550 backup_database
551 test_begin_subtest "override config from \${HOME}/.notmuch-config.work (via args)"
552 ovconfig=${HOME}/.notmuch-config.work
553 cp ${NOTMUCH_CONFIG} ${ovconfig}
554 old_NOTMUCH_CONFIG=${NOTMUCH_CONFIG}
555 unset NOTMUCH_CONFIG
556 notmuch --config=${ovconfig} config set test.key1 overridden-profile
557 cat c_head - c_tail <<'EOF' | test_C ${MAIL_DIR} %NULL% work
558 {
559    EXPECT0(notmuch_database_get_config (db, "test.key1", &val));
560    printf("test.key1 = %s\n", val);
561    EXPECT0(notmuch_database_get_config (db, "test.key2", &val));
562    printf("test.key2 = %s\n", val);
563 }
564 EOF
565 #rm -f ${ovconfig}
566 export NOTMUCH_CONFIG=${old_NOTMUCH_CONFIG}
567 cat <<'EOF' >EXPECTED
568 == stdout ==
569 test.key1 = overridden-profile
570 test.key2 = testvalue2
571 == stderr ==
572 EOF
573 test_expect_equal_file EXPECTED OUTPUT
574 restore_database
575
576 test_begin_subtest "no config, fail to open database"
577 old_NOTMUCH_CONFIG=${NOTMUCH_CONFIG}
578 unset NOTMUCH_CONFIG
579 cat c_head - c_tail <<'EOF' | test_C %NULL% '' %NULL%
580 {
581    printf("NOT RUN");
582 }
583 EOF
584 export NOTMUCH_CONFIG=${old_NOTMUCH_CONFIG}
585 cat <<'EOF' >EXPECTED
586 == stdout ==
587 == stderr ==
588 error opening database
589 No database found
590 Error: could not locate database.
591
592 EOF
593 test_expect_equal_file EXPECTED OUTPUT
594
595 test_begin_subtest "open database from NOTMUCH_DATABASE"
596 old_NOTMUCH_CONFIG=${NOTMUCH_CONFIG}
597 unset NOTMUCH_CONFIG
598 export NOTMUCH_DATABASE=${MAIL_DIR}
599 cat c_head - c_tail <<'EOF' | test_C %NULL% '' %NULL%
600 {
601    EXPECT0(notmuch_database_get_config (db, "test.key1", &val));
602    printf("test.key1 = %s\n", val);
603    EXPECT0(notmuch_database_get_config (db, "test.key2", &val));
604    printf("test.key2 = %s\n", val);
605 }
606 EOF
607 export NOTMUCH_CONFIG=${old_NOTMUCH_CONFIG}
608 unset NOTMUCH_DATABASE
609 cat <<'EOF' >EXPECTED
610 == stdout ==
611 test.key1 = testvalue1
612 test.key2 = testvalue2
613 == stderr ==
614 EOF
615 test_expect_equal_file EXPECTED OUTPUT
616
617 test_begin_subtest "NOTMUCH_DATABASE overrides config"
618 cp notmuch-config notmuch-config.bak
619 notmuch config set database.path /nonexistent
620 export NOTMUCH_DATABASE=${MAIL_DIR}
621 cat c_head - c_tail <<'EOF' | test_C %NULL% '' %NULL%
622 {
623    EXPECT0(notmuch_database_get_config (db, "test.key1", &val));
624    printf("test.key1 = %s\n", val);
625    EXPECT0(notmuch_database_get_config (db, "test.key2", &val));
626    printf("test.key2 = %s\n", val);
627 }
628 EOF
629 export NOTMUCH_CONFIG=${old_NOTMUCH_CONFIG}
630 unset NOTMUCH_DATABASE
631 cat <<'EOF' >EXPECTED
632 == stdout ==
633 test.key1 = testvalue1
634 test.key2 = testvalue2
635 == stderr ==
636 EOF
637 cp notmuch-config.bak notmuch-config
638 test_expect_equal_file EXPECTED OUTPUT
639
640 cat <<EOF > c_head2
641 #include <notmuch-test.h>
642
643 int main (int argc, char** argv)
644 {
645    notmuch_database_t *db;
646    char *val;
647    notmuch_status_t stat;
648    char *msg = NULL;
649
650    for (int i = 1; i < argc; i++)
651       if (strcmp (argv[i], "%NULL%") == 0) argv[i] = NULL;
652
653    stat = notmuch_database_load_config (argv[1],
654                                         argv[2],
655                                         argv[3],
656                                         &db,
657                                         &msg);
658    if (stat != NOTMUCH_STATUS_SUCCESS  && stat != NOTMUCH_STATUS_NO_CONFIG) {
659      fprintf (stderr, "error opening database\n%d: %s\n%s\n", stat,
660               notmuch_status_to_string (stat), msg ? msg : "");
661      exit (1);
662    }
663 EOF
664
665
666 test_begin_subtest "notmuch_database_get_config (ndlc)"
667 cat c_head2 - c_tail <<'EOF' | test_C ${MAIL_DIR} %NULL% %NULL%
668 {
669    EXPECT0(notmuch_database_get_config (db, "test.key1", &val));
670    printf("test.key1 = %s\n", val);
671    EXPECT0(notmuch_database_get_config (db, "test.key2", &val));
672    printf("test.key2 = %s\n", val);
673 }
674 EOF
675 cat <<'EOF' >EXPECTED
676 == stdout ==
677 test.key1 = testvalue1
678 test.key2 = testvalue2
679 == stderr ==
680 EOF
681 test_expect_equal_file EXPECTED OUTPUT
682
683
684 test_begin_subtest "notmuch_database_get_config_list: all pairs (ndlc)"
685 cat c_head2 - c_tail <<'EOF' | test_C ${MAIL_DIR} ${NOTMUCH_CONFIG} %NULL%
686 {
687    notmuch_config_list_t *list;
688    EXPECT0(notmuch_database_get_config_list (db, "", &list));
689    for (; notmuch_config_list_valid (list); notmuch_config_list_move_to_next (list)) {
690       printf("%s %s\n", notmuch_config_list_key (list), notmuch_config_list_value(list));
691    }
692    notmuch_config_list_destroy (list);
693 }
694 EOF
695 cat <<'EOF' >EXPECTED
696 == stdout ==
697 aaabefore beforeval
698 key with spaces value, with, spaces!
699 test.key1 testvalue1
700 test.key2 testvalue2
701 zzzafter afterval
702 == stderr ==
703 EOF
704 test_expect_equal_file EXPECTED OUTPUT
705
706 test_begin_subtest "notmuch_database_get_config_list: one prefix (ndlc)"
707 cat c_head2 - c_tail <<'EOF' | test_C ${MAIL_DIR} ${NOTMUCH_CONFIG} %NULL%
708 {
709    notmuch_config_list_t *list;
710    EXPECT0(notmuch_database_get_config_list (db, "test.key", &list));
711    for (; notmuch_config_list_valid (list); notmuch_config_list_move_to_next (list)) {
712       printf("%s %s\n", notmuch_config_list_key (list), notmuch_config_list_value(list));
713    }
714    notmuch_config_list_destroy (list);
715 }
716 EOF
717 cat <<'EOF' >EXPECTED
718 == stdout ==
719 test.key1 testvalue1
720 test.key2 testvalue2
721 == stderr ==
722 EOF
723 test_expect_equal_file EXPECTED OUTPUT
724
725 test_begin_subtest "list by keys (ndlc)"
726 notmuch config set search.exclude_tags "foo;bar;fub"
727 notmuch config set new.ignore "sekrit_junk"
728 cat c_head2 - c_tail <<'EOF' | test_C ${MAIL_DIR} %NULL% %NULL%
729 {
730     notmuch_config_key_t key;
731     for (key = NOTMUCH_CONFIG_FIRST;
732          key < NOTMUCH_CONFIG_LAST;
733          key = (notmuch_config_key_t)(key + 1)) {
734         const char *val = notmuch_config_get (db, key);
735         printf("%02d: '%s'\n", key, val ? val : "NULL" );
736     }
737 }
738 EOF
739 cat <<'EOF' >EXPECTED
740 == stdout ==
741 00: 'MAIL_DIR'
742 01: 'MAIL_DIR'
743 02: 'MAIL_DIR/.notmuch/hooks'
744 03: 'MAIL_DIR/.notmuch/backups'
745 04: 'foo;bar;fub'
746 05: 'unread;inbox'
747 06: 'sekrit_junk'
748 07: 'true'
749 08: 'test_suite@notmuchmail.org'
750 09: 'test_suite_other@notmuchmail.org;test_suite@otherdomain.org'
751 10: 'Notmuch Test Suite'
752 11: '8000'
753 12: 'NULL'
754 == stderr ==
755 EOF
756 test_expect_equal_file EXPECTED OUTPUT
757
758 test_begin_subtest "load default values (ndlc, nonexistent config)"
759 cat c_head2 - c_tail <<'EOF' | test_C ${MAIL_DIR} /nonexistent %NULL%
760 {
761     notmuch_config_key_t key;
762     for (key = NOTMUCH_CONFIG_FIRST;
763          key < NOTMUCH_CONFIG_LAST;
764          key = (notmuch_config_key_t)(key + 1)) {
765         const char *val = notmuch_config_get (db, key);
766         printf("%02d: '%s'\n", key, val ? val : "NULL" );
767     }
768 }
769 EOF
770
771 _libconfig_sanitize < OUTPUT > OUTPUT.clean
772
773 cat <<'EOF' >EXPECTED
774 == stdout ==
775 00: 'MAIL_DIR'
776 01: 'MAIL_DIR'
777 02: 'MAIL_DIR/.notmuch/hooks'
778 03: 'MAIL_DIR/.notmuch/backups'
779 04: ''
780 05: 'unread;inbox'
781 06: ''
782 07: 'true'
783 08: 'USERNAME@localhost'
784 09: 'NULL'
785 10: 'USER_FULL_NAME'
786 11: '8000'
787 12: 'NULL'
788 == stderr ==
789 EOF
790 test_expect_equal_file EXPECTED OUTPUT.clean
791
792 backup_database
793 test_begin_subtest "override config from \${HOME}/.notmuch-config (ndlc)"
794 ovconfig=${HOME}/.notmuch-config
795 cp ${NOTMUCH_CONFIG} ${ovconfig}
796 old_NOTMUCH_CONFIG=${NOTMUCH_CONFIG}
797 unset NOTMUCH_CONFIG
798 notmuch --config=${ovconfig} config set test.key1 overridden-home
799 cat c_head2 - c_tail <<'EOF' | test_C ${MAIL_DIR} %NULL% %NULL%
800 {
801    EXPECT0(notmuch_database_get_config (db, "test.key1", &val));
802    printf("test.key1 = %s\n", val);
803    EXPECT0(notmuch_database_get_config (db, "test.key2", &val));
804    printf("test.key2 = %s\n", val);
805 }
806 EOF
807 rm -f ${ovconfig}
808 export NOTMUCH_CONFIG=${old_NOTMUCH_CONFIG}
809 cat <<'EOF' >EXPECTED
810 == stdout ==
811 test.key1 = overridden-home
812 test.key2 = testvalue2
813 == stderr ==
814 EOF
815 test_expect_equal_file EXPECTED OUTPUT
816 restore_database
817
818 test_begin_subtest "notmuch_config_get_pairs: prefix (ndlc)"
819 cat c_head2 - c_tail <<'EOF' | test_C ${MAIL_DIR} ${NOTMUCH_CONFIG} %NULL%
820 {
821    notmuch_config_pairs_t *list;
822    for (list =  notmuch_config_get_pairs (db, "user.");
823         notmuch_config_pairs_valid (list);
824         notmuch_config_pairs_move_to_next (list)) {
825      printf("%s %s\n", notmuch_config_pairs_key (list), notmuch_config_pairs_value(list));
826    }
827    notmuch_config_pairs_destroy (list);
828 }
829 EOF
830 cat <<'EOF' >EXPECTED
831 == stdout ==
832 user.name Notmuch Test Suite
833 user.other_email test_suite_other@notmuchmail.org;test_suite@otherdomain.org
834 user.primary_email test_suite@notmuchmail.org
835 == stderr ==
836 EOF
837 test_expect_equal_file EXPECTED OUTPUT
838
839 test_begin_subtest "notmuch_config_get_pairs: all pairs (ndlc)"
840 cat c_head2 - c_tail <<'EOF' | test_C ${MAIL_DIR} ${NOTMUCH_CONFIG} %NULL%
841 {
842    notmuch_config_pairs_t *list;
843    for (list =  notmuch_config_get_pairs (db, "");
844         notmuch_config_pairs_valid (list);
845         notmuch_config_pairs_move_to_next (list)) {
846      printf("%s %s\n", notmuch_config_pairs_key (list), notmuch_config_pairs_value(list));
847    }
848    notmuch_config_pairs_destroy (list);
849 }
850 EOF
851 cat <<'EOF' >EXPECTED
852 == stdout ==
853 aaabefore beforeval
854 database.autocommit 8000
855 database.backup_dir MAIL_DIR/.notmuch/backups
856 database.hook_dir MAIL_DIR/.notmuch/hooks
857 database.mail_root MAIL_DIR
858 database.path MAIL_DIR
859 key with spaces value, with, spaces!
860 maildir.synchronize_flags true
861 new.ignore sekrit_junk
862 new.tags unread;inbox
863 search.exclude_tags foo;bar;fub
864 show.extra_headers (null)
865 test.key1 testvalue1
866 test.key2 testvalue2
867 user.name Notmuch Test Suite
868 user.other_email test_suite_other@notmuchmail.org;test_suite@otherdomain.org
869 user.primary_email test_suite@notmuchmail.org
870 zzzafter afterval
871 == stderr ==
872 EOF
873 test_expect_equal_file EXPECTED OUTPUT
874
875 cat <<EOF > c_head3
876 #include <notmuch-test.h>
877 int main (int argc, char **argv) {
878   notmuch_status_t stat;
879   notmuch_database_t *db = NULL;
880 EOF
881
882 cat <<EOF > c_tail3
883   printf("db == NULL: %d\n", db == NULL);
884 }
885 EOF
886
887 test_begin_subtest "open: database set to null on missing config"
888 cat c_head3 - c_tail3 <<'EOF' | test_C ${MAIL_DIR}
889   notmuch_status_t st = notmuch_database_open_with_config(argv[1],
890                                                           NOTMUCH_DATABASE_MODE_READ_ONLY,
891                                                           "/nonexistent", NULL, &db, NULL);
892 EOF
893 cat <<EOF> EXPECTED
894 == stdout ==
895 db == NULL: 1
896 == stderr ==
897 EOF
898 test_expect_equal_file EXPECTED OUTPUT
899
900 test_begin_subtest "open: database set to null on missing config (env)"
901 old_NOTMUCH_CONFIG=${NOTMUCH_CONFIG}
902 export NOTMUCH_CONFIG="/nonexistent"
903 cat c_head3 - c_tail3 <<'EOF' | test_C ${MAIL_DIR}
904   notmuch_status_t st = notmuch_database_open_with_config(argv[1],
905                                                           NOTMUCH_DATABASE_MODE_READ_ONLY,
906                                                           NULL, NULL, &db, NULL);
907 EOF
908 export NOTMUCH_CONFIG=${old_NOTMUCH_CONFIG}
909 cat <<EOF> EXPECTED
910 == stdout ==
911 db == NULL: 1
912 == stderr ==
913 EOF
914 test_expect_equal_file EXPECTED OUTPUT
915
916 test_begin_subtest "create: database set to null on missing config"
917 cat c_head3 - c_tail3 <<'EOF' | test_C ${MAIL_DIR} "/nonexistent"
918   notmuch_status_t st = notmuch_database_create_with_config(argv[1],argv[2], NULL, &db, NULL);
919 EOF
920 cat <<EOF> EXPECTED
921 == stdout ==
922 db == NULL: 1
923 == stderr ==
924 EOF
925 test_expect_equal_file EXPECTED OUTPUT
926
927 test_begin_subtest "create: database set to null on missing config (env)"
928 old_NOTMUCH_CONFIG=${NOTMUCH_CONFIG}
929 export NOTMUCH_CONFIG="/nonexistent"
930 cat c_head3 - c_tail3 <<'EOF' | test_C ${MAIL_DIR}
931   notmuch_status_t st = notmuch_database_create_with_config(argv[1],
932                                                           NULL, NULL, &db, NULL);
933 EOF
934 export NOTMUCH_CONFIG=${old_NOTMUCH_CONFIG}
935 cat <<EOF> EXPECTED
936 == stdout ==
937 db == NULL: 1
938 == stderr ==
939 EOF
940 test_expect_equal_file EXPECTED OUTPUT
941
942 test_begin_subtest "load_config: database set non-null on missing config"
943 cat c_head3 - c_tail3 <<'EOF' | test_C ${MAIL_DIR} "/nonexistent"
944   notmuch_status_t st = notmuch_database_load_config(argv[1],argv[2], NULL, &db, NULL);
945 EOF
946 cat <<EOF> EXPECTED
947 == stdout ==
948 db == NULL: 0
949 == stderr ==
950 EOF
951 test_expect_equal_file EXPECTED OUTPUT
952
953 test_begin_subtest "load_config: database non-null on missing config (env)"
954 old_NOTMUCH_CONFIG=${NOTMUCH_CONFIG}
955 export NOTMUCH_CONFIG="/nonexistent"
956 cat c_head3 - c_tail3 <<'EOF' | test_C ${MAIL_DIR}
957   notmuch_status_t st = notmuch_database_load_config(argv[1], NULL, NULL, &db, NULL);
958 EOF
959 export NOTMUCH_CONFIG=${old_NOTMUCH_CONFIG}
960 cat <<EOF> EXPECTED
961 == stdout ==
962 db == NULL: 0
963 == stderr ==
964 EOF
965 test_expect_equal_file EXPECTED OUTPUT
966
967 test_begin_subtest "load_config: database set to NULL on fatal error"
968 cat c_head3 - c_tail3 <<'EOF' | test_C
969   notmuch_status_t st = notmuch_database_load_config("relative", NULL, NULL, &db, NULL);
970 EOF
971 cat <<EOF> EXPECTED
972 == stdout ==
973 db == NULL: 1
974 == stderr ==
975 EOF
976 test_expect_equal_file EXPECTED OUTPUT
977
978 test_begin_subtest "open: database parameter overrides implicit config"
979 cp $NOTMUCH_CONFIG ${NOTMUCH_CONFIG}.bak
980 notmuch config set database.path ${MAIL_DIR}/nonexistent
981 cat c_head3 - c_tail3 <<'EOF' | test_C ${MAIL_DIR}
982   const char *path = NULL;
983   notmuch_status_t st = notmuch_database_open_with_config(argv[1],
984                                                           NOTMUCH_DATABASE_MODE_READ_ONLY,
985                                                           NULL, NULL, &db, NULL);
986   printf ("status: %d\n", st);
987   path = notmuch_database_get_path (db);
988   printf ("path: %s\n", path ? path : "(null)");
989 EOF
990 cp ${NOTMUCH_CONFIG}.bak ${NOTMUCH_CONFIG}
991 cat <<EOF> EXPECTED
992 == stdout ==
993 status: 0
994 path: MAIL_DIR
995 db == NULL: 0
996 == stderr ==
997 EOF
998 notmuch_dir_sanitize < OUTPUT > OUTPUT.clean
999 test_expect_equal_file EXPECTED OUTPUT.clean
1000
1001 cat <<EOF > c_body
1002   notmuch_status_t st = notmuch_database_open_with_config(NULL,
1003                                                           NOTMUCH_DATABASE_MODE_READ_ONLY,
1004                                                           "", NULL, &db, NULL);
1005   printf ("status == SUCCESS: %d\n", st == NOTMUCH_STATUS_SUCCESS);
1006   if (db) {
1007     const char *mail_root = NULL;
1008     mail_root = notmuch_config_get (db, NOTMUCH_CONFIG_MAIL_ROOT);
1009     printf ("mail_root: %s\n", mail_root ? mail_root : "(null)");
1010   }
1011 EOF
1012
1013 cat <<EOF> EXPECTED.common
1014 == stdout ==
1015 status == SUCCESS: 0
1016 db == NULL: 1
1017 == stderr ==
1018 EOF
1019
1020 test_begin_subtest "open/error: config=empty with no mail root in db "
1021 old_NOTMUCH_CONFIG=${NOTMUCH_CONFIG}
1022 unset NOTMUCH_CONFIG
1023 cat c_head3 c_body c_tail3 | test_C
1024 export NOTMUCH_CONFIG=${old_NOTMUCH_CONFIG}
1025 notmuch_dir_sanitize < OUTPUT > OUTPUT.clean
1026 test_expect_equal_file EXPECTED.common OUTPUT.clean
1027
1028 test_begin_subtest "open/error: config=empty with no mail root in db (xdg)"
1029 old_NOTMUCH_CONFIG=${NOTMUCH_CONFIG}
1030 unset NOTMUCH_CONFIG
1031 backup_database
1032 mkdir -p home/.local/share/notmuch
1033 mv mail/.notmuch home/.local/share/notmuch/default
1034 cat c_head3 c_body c_tail3 | test_C
1035 restore_database
1036 export NOTMUCH_CONFIG=${old_NOTMUCH_CONFIG}
1037 notmuch_dir_sanitize < OUTPUT > OUTPUT.clean
1038 test_expect_equal_file EXPECTED.common OUTPUT.clean
1039
1040 test_done