]> git.notmuchmail.org Git - notmuch/blob - test/T590-libconfig.sh
config: ignore leading/trailing spaces in ';'-delimited lists
[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 <string.h>
27 #include <stdlib.h>
28 #include <notmuch-test.h>
29
30 int main (int argc, char** argv)
31 {
32    notmuch_database_t *db;
33    char *val;
34    notmuch_status_t stat;
35    char *msg = NULL;
36
37    for (int i = 1; i < argc; i++)
38       if (strcmp (argv[i], "%NULL%") == 0) argv[i] = NULL;
39
40    stat = notmuch_database_open_with_config (argv[1],
41                                               NOTMUCH_DATABASE_MODE_READ_WRITE,
42                                               argv[2],
43                                               argv[3],
44                                               &db,
45                                               &msg);
46    if (stat != NOTMUCH_STATUS_SUCCESS) {
47      fprintf (stderr, "error opening database\n%s\n%s\n", notmuch_status_to_string (stat), msg ? msg : "");
48      exit (1);
49    }
50 EOF
51
52 cat <<EOF > c_tail
53    EXPECT0(notmuch_database_destroy(db));
54 }
55 EOF
56
57 test_begin_subtest "notmuch_database_{set,get}_config"
58 cat c_head - c_tail <<'EOF' | test_C ${MAIL_DIR} ${NOTMUCH_CONFIG}
59 {
60    EXPECT0(notmuch_database_set_config (db, "test.key1", "testvalue1"));
61    EXPECT0(notmuch_database_set_config (db, "test.key2", "testvalue2"));
62    EXPECT0(notmuch_database_get_config (db, "test.key1", &val));
63    printf("test.key1 = %s\n", val);
64    EXPECT0(notmuch_database_get_config (db, "test.key2", &val));
65    printf("test.key2 = %s\n", val);
66 }
67 EOF
68 cat <<'EOF' >EXPECTED
69 == stdout ==
70 test.key1 = testvalue1
71 test.key2 = testvalue2
72 == stderr ==
73 EOF
74 test_expect_equal_file EXPECTED OUTPUT
75
76
77 test_begin_subtest "notmuch_database_get_config_list: empty list"
78 cat c_head - c_tail <<'EOF' | test_C ${MAIL_DIR} ${NOTMUCH_CONFIG} %NULL%
79 {
80    notmuch_config_list_t *list;
81    EXPECT0(notmuch_database_get_config_list (db, "nonexistent", &list));
82    printf("valid = %d\n", notmuch_config_list_valid (list));
83    notmuch_config_list_destroy (list);
84 }
85 EOF
86 cat <<'EOF' >EXPECTED
87 == stdout ==
88 valid = 0
89 == stderr ==
90 EOF
91 test_expect_equal_file EXPECTED OUTPUT
92
93 test_begin_subtest "notmuch_database_get_config_list: closed db"
94 cat c_head - c_tail <<'EOF' | test_C ${MAIL_DIR}
95 {
96    notmuch_config_list_t *list;
97    EXPECT0(notmuch_database_close (db));
98    stat = notmuch_database_get_config_list (db, "nonexistent", &list);
99    printf("%d\n", stat == NOTMUCH_STATUS_XAPIAN_EXCEPTION);
100 }
101 EOF
102 cat <<'EOF' >EXPECTED
103 == stdout ==
104 1
105 == stderr ==
106 EOF
107 test_expect_equal_file EXPECTED OUTPUT
108
109 test_begin_subtest "notmuch_database_get_config_list: all pairs"
110 cat c_head - c_tail <<'EOF' | test_C ${MAIL_DIR} ${NOTMUCH_CONFIG} %NULL%
111 {
112    notmuch_config_list_t *list;
113    EXPECT0(notmuch_database_set_config (db, "zzzafter", "afterval"));
114    EXPECT0(notmuch_database_set_config (db, "aaabefore", "beforeval"));
115    EXPECT0(notmuch_database_get_config_list (db, "", &list));
116    for (; notmuch_config_list_valid (list); notmuch_config_list_move_to_next (list)) {
117       printf("%s %s\n", notmuch_config_list_key (list), notmuch_config_list_value(list));
118    }
119    notmuch_config_list_destroy (list);
120 }
121 EOF
122 cat <<'EOF' >EXPECTED
123 == stdout ==
124 aaabefore beforeval
125 test.key1 testvalue1
126 test.key2 testvalue2
127 zzzafter afterval
128 == stderr ==
129 EOF
130 test_expect_equal_file EXPECTED OUTPUT
131
132 test_begin_subtest "notmuch_database_get_config_list: all pairs (closed db)"
133 cat c_head - c_tail <<'EOF' | test_C ${MAIL_DIR}
134 {
135    notmuch_config_list_t *list;
136    EXPECT0(notmuch_database_get_config_list (db, "", &list));
137    EXPECT0(notmuch_database_close (db));
138    for (; notmuch_config_list_valid (list); notmuch_config_list_move_to_next (list)) {
139       printf("%s %d\n", notmuch_config_list_key (list), NULL == notmuch_config_list_value(list));
140    }
141    notmuch_config_list_destroy (list);
142 }
143 EOF
144 cat <<'EOF' >EXPECTED
145 == stdout ==
146 aaabefore 1
147 test.key1 1
148 test.key2 1
149 zzzafter 1
150 == stderr ==
151 EOF
152 test_expect_equal_file EXPECTED OUTPUT
153
154 test_begin_subtest "notmuch_database_get_config_list: one prefix"
155 cat c_head - c_tail <<'EOF' | test_C ${MAIL_DIR} ${NOTMUCH_CONFIG} %NULL%
156 {
157    notmuch_config_list_t *list;
158    EXPECT0(notmuch_database_get_config_list (db, "test.key", &list));
159    for (; notmuch_config_list_valid (list); notmuch_config_list_move_to_next (list)) {
160       printf("%s %s\n", notmuch_config_list_key (list), notmuch_config_list_value(list));
161    }
162    notmuch_config_list_destroy (list);
163 }
164 EOF
165 cat <<'EOF' >EXPECTED
166 == stdout ==
167 test.key1 testvalue1
168 test.key2 testvalue2
169 == stderr ==
170 EOF
171 test_expect_equal_file EXPECTED OUTPUT
172
173 test_begin_subtest "dump config"
174 cat c_head - c_tail <<'EOF' | test_C ${MAIL_DIR} ${NOTMUCH_CONFIG} %NULL%
175 {
176     EXPECT0(notmuch_database_set_config (db, "key with spaces", "value, with, spaces!"));
177 }
178 EOF
179 notmuch dump --include=config >OUTPUT
180 cat <<'EOF' >EXPECTED
181 #notmuch-dump batch-tag:3 config
182 #@ aaabefore beforeval
183 #@ key%20with%20spaces value,%20with,%20spaces%21
184 #@ test.key1 testvalue1
185 #@ test.key2 testvalue2
186 #@ zzzafter afterval
187 EOF
188 test_expect_equal_file EXPECTED OUTPUT
189
190 test_begin_subtest "restore config"
191 notmuch dump --include=config >EXPECTED
192 cat c_head - c_tail <<'EOF' | test_C ${MAIL_DIR} ${NOTMUCH_CONFIG} %NULL%
193 {
194     EXPECT0(notmuch_database_set_config (db, "test.key1", "mutatedvalue"));
195 }
196 EOF
197 notmuch restore --include=config <EXPECTED
198 notmuch dump --include=config >OUTPUT
199 test_expect_equal_file EXPECTED OUTPUT
200
201 backup_database
202 test_begin_subtest "override config from file"
203 notmuch config set test.key1 overridden
204 cat c_head - c_tail <<'EOF' | test_C ${MAIL_DIR} ${NOTMUCH_CONFIG}
205 {
206    EXPECT0(notmuch_database_get_config (db, "test.key1", &val));
207    printf("test.key1 = %s\n", val);
208    EXPECT0(notmuch_database_get_config (db, "test.key2", &val));
209    printf("test.key2 = %s\n", val);
210 }
211 EOF
212 cat <<'EOF' >EXPECTED
213 == stdout ==
214 test.key1 = overridden
215 test.key2 = testvalue2
216 == stderr ==
217 EOF
218 test_expect_equal_file EXPECTED OUTPUT
219 restore_database
220
221 test_begin_subtest "NOTMUCH_CONFIG_HOOK_DIR: traditional"
222 cat c_head - c_tail <<'EOF' | test_C ${MAIL_DIR} ${NOTMUCH_CONFIG} %NULL%
223 {
224    const char *val = notmuch_config_get (db, NOTMUCH_CONFIG_HOOK_DIR);
225    printf("database.hook_dir = %s\n", val);
226 }
227 EOF
228 cat <<'EOF' >EXPECTED
229 == stdout ==
230 database.hook_dir = MAIL_DIR/.notmuch/hooks
231 == stderr ==
232 EOF
233 test_expect_equal_file EXPECTED OUTPUT
234
235 test_begin_subtest "NOTMUCH_CONFIG_HOOK_DIR: xdg"
236 dir="${HOME}/.config/notmuch/default/hooks"
237 mkdir -p $dir
238 cat c_head - c_tail <<'EOF' | test_C ${MAIL_DIR} ${NOTMUCH_CONFIG} %NULL%
239 {
240    const char *val = notmuch_config_get (db, NOTMUCH_CONFIG_HOOK_DIR);
241    printf("database.hook_dir = %s\n", val);
242 }
243 EOF
244 cat <<'EOF' >EXPECTED
245 == stdout ==
246 database.hook_dir = CWD/home/.config/notmuch/default/hooks
247 == stderr ==
248 EOF
249 rmdir $dir
250 test_expect_equal_file EXPECTED OUTPUT
251
252 test_begin_subtest "notmuch_config_get_values"
253 cat c_head - c_tail <<'EOF' | test_C ${MAIL_DIR} ${NOTMUCH_CONFIG} %NULL%
254 {
255     notmuch_config_values_t *values;
256     EXPECT0(notmuch_config_set (db, NOTMUCH_CONFIG_NEW_TAGS, "a;b;c"));
257     for (values = notmuch_config_get_values (db, NOTMUCH_CONFIG_NEW_TAGS);
258          notmuch_config_values_valid (values);
259          notmuch_config_values_move_to_next (values))
260     {
261           puts (notmuch_config_values_get (values));
262     }
263 }
264 EOF
265 cat <<'EOF' >EXPECTED
266 == stdout ==
267 a
268 b
269 c
270 == stderr ==
271 EOF
272 test_expect_equal_file EXPECTED OUTPUT
273 restore_database
274
275 test_begin_subtest "notmuch_config_get_values (ignore leading/trailing whitespace)"
276 cat c_head - c_tail <<'EOF' | test_C ${MAIL_DIR} ${NOTMUCH_CONFIG} %NULL%
277 {
278     notmuch_config_values_t *values;
279     EXPECT0(notmuch_config_set (db, NOTMUCH_CONFIG_NEW_TAGS, " a ; b c ; d "));
280     for (values = notmuch_config_get_values (db, NOTMUCH_CONFIG_NEW_TAGS);
281          notmuch_config_values_valid (values);
282          notmuch_config_values_move_to_next (values))
283     {
284           puts (notmuch_config_values_get (values));
285     }
286 }
287 EOF
288 cat <<'EOF' >EXPECTED
289 == stdout ==
290 a
291 b c
292 d
293 == stderr ==
294 EOF
295 test_expect_equal_file EXPECTED OUTPUT
296 restore_database
297
298 test_begin_subtest "notmuch_config_get_values_string"
299 cat c_head - c_tail <<'EOF' | test_C ${MAIL_DIR} ${NOTMUCH_CONFIG} %NULL%
300 {
301     notmuch_config_values_t *values;
302     EXPECT0(notmuch_database_set_config (db, "test.list", "x;y;z"));
303     for (values = notmuch_config_get_values_string (db, "test.list");
304          notmuch_config_values_valid (values);
305          notmuch_config_values_move_to_next (values))
306     {
307           puts (notmuch_config_values_get (values));
308     }
309 }
310 EOF
311 cat <<'EOF' >EXPECTED
312 == stdout ==
313 x
314 y
315 z
316 == stderr ==
317 EOF
318 test_expect_equal_file EXPECTED OUTPUT
319 restore_database
320
321 test_begin_subtest "notmuch_config_get_values (restart)"
322 cat c_head - c_tail <<'EOF' | test_C ${MAIL_DIR} ${NOTMUCH_CONFIG} %NULL%
323 {
324     notmuch_config_values_t *values;
325     EXPECT0(notmuch_config_set (db, NOTMUCH_CONFIG_NEW_TAGS, "a;b;c"));
326     for (values = notmuch_config_get_values (db, NOTMUCH_CONFIG_NEW_TAGS);
327          notmuch_config_values_valid (values);
328          notmuch_config_values_move_to_next (values))
329     {
330           puts (notmuch_config_values_get (values));
331     }
332     for (notmuch_config_values_start (values);
333          notmuch_config_values_valid (values);
334          notmuch_config_values_move_to_next (values))
335     {
336           puts (notmuch_config_values_get (values));
337     }
338 }
339 EOF
340 cat <<'EOF' >EXPECTED
341 == stdout ==
342 a
343 b
344 c
345 a
346 b
347 c
348 == stderr ==
349 EOF
350 test_expect_equal_file EXPECTED OUTPUT
351 restore_database
352
353 backup_database
354 test_begin_subtest "notmuch_config_get_values, trailing ;"
355 cat c_head - c_tail <<'EOF' | test_C ${MAIL_DIR} ${NOTMUCH_CONFIG} %NULL%
356 {
357     notmuch_config_values_t *values;
358     EXPECT0(notmuch_config_set (db, NOTMUCH_CONFIG_NEW_TAGS, "a;b;c"));
359     for (values = notmuch_config_get_values (db, NOTMUCH_CONFIG_NEW_TAGS);
360          notmuch_config_values_valid (values);
361          notmuch_config_values_move_to_next (values))
362     {
363           puts (notmuch_config_values_get (values));
364     }
365 }
366 EOF
367 cat <<'EOF' >EXPECTED
368 == stdout ==
369 a
370 b
371 c
372 == stderr ==
373 EOF
374 test_expect_equal_file EXPECTED OUTPUT
375 restore_database
376
377 backup_database
378 test_begin_subtest "get config by key"
379 cat c_head - c_tail <<'EOF' | test_C ${MAIL_DIR} ${NOTMUCH_CONFIG}
380 {
381    printf("before = %s\n", notmuch_config_get (db, NOTMUCH_CONFIG_SYNC_MAILDIR_FLAGS));
382    EXPECT0(notmuch_database_set_config (db, "maildir.synchronize_flags", "false"));
383    printf("after = %s\n", notmuch_config_get (db, NOTMUCH_CONFIG_SYNC_MAILDIR_FLAGS));
384 }
385 EOF
386 cat <<'EOF' >EXPECTED
387 == stdout ==
388 before = true
389 after = false
390 == stderr ==
391 EOF
392 test_expect_equal_file EXPECTED OUTPUT
393 restore_database
394
395 backup_database
396 test_begin_subtest "set config by key"
397 notmuch config set test.key1 overridden
398 cat c_head - c_tail <<'EOF' | test_C ${MAIL_DIR} ${NOTMUCH_CONFIG}
399 {
400    printf("before = %s\n", notmuch_config_get (db, NOTMUCH_CONFIG_SYNC_MAILDIR_FLAGS));
401    EXPECT0(notmuch_config_set (db, NOTMUCH_CONFIG_SYNC_MAILDIR_FLAGS, "false"));
402    printf("after = %s\n", notmuch_config_get (db, NOTMUCH_CONFIG_SYNC_MAILDIR_FLAGS));
403 }
404 EOF
405 cat <<'EOF' >EXPECTED
406 == stdout ==
407 before = true
408 after = false
409 == stderr ==
410 EOF
411 test_expect_equal_file EXPECTED OUTPUT
412 restore_database
413
414 test_begin_subtest "load default values"
415 export MAILDIR=${MAIL_DIR}
416 cat c_head - c_tail <<'EOF' | test_C ${MAIL_DIR} '' %NULL%
417 {
418     notmuch_config_key_t key;
419     for (key = NOTMUCH_CONFIG_FIRST;
420          key < NOTMUCH_CONFIG_LAST;
421          key = (notmuch_config_key_t)(key + 1)) {
422         const char *val = notmuch_config_get (db, key);
423         printf("%02d: '%s'\n", key, val ? val : "NULL" );
424     }
425 }
426 EOF
427
428 _libconfig_sanitize < OUTPUT > OUTPUT.clean
429
430 cat <<'EOF' >EXPECTED
431 == stdout ==
432 00: 'MAIL_DIR'
433 01: 'MAIL_DIR'
434 02: 'MAIL_DIR/.notmuch/hooks'
435 03: 'MAIL_DIR/.notmuch/backups'
436 04: ''
437 05: 'unread;inbox'
438 06: ''
439 07: 'true'
440 08: 'USERNAME@localhost'
441 09: 'NULL'
442 10: 'USER_FULL_NAME'
443 11: '8000'
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 <string.h>
643 #include <stdlib.h>
644 #include <notmuch-test.h>
645
646 int main (int argc, char** argv)
647 {
648    notmuch_database_t *db;
649    char *val;
650    notmuch_status_t stat;
651    char *msg = NULL;
652
653    for (int i = 1; i < argc; i++)
654       if (strcmp (argv[i], "%NULL%") == 0) argv[i] = NULL;
655
656    stat = notmuch_database_load_config (argv[1],
657                                         argv[2],
658                                         argv[3],
659                                         &db,
660                                         &msg);
661    if (stat != NOTMUCH_STATUS_SUCCESS  && stat != NOTMUCH_STATUS_NO_CONFIG) {
662      fprintf (stderr, "error opening database\n%d: %s\n%s\n", stat,
663               notmuch_status_to_string (stat), msg ? msg : "");
664      exit (1);
665    }
666 EOF
667
668
669 test_begin_subtest "notmuch_database_get_config (ndlc)"
670 cat c_head2 - c_tail <<'EOF' | test_C ${MAIL_DIR} %NULL% %NULL%
671 {
672    EXPECT0(notmuch_database_get_config (db, "test.key1", &val));
673    printf("test.key1 = %s\n", val);
674    EXPECT0(notmuch_database_get_config (db, "test.key2", &val));
675    printf("test.key2 = %s\n", val);
676 }
677 EOF
678 cat <<'EOF' >EXPECTED
679 == stdout ==
680 test.key1 = testvalue1
681 test.key2 = testvalue2
682 == stderr ==
683 EOF
684 test_expect_equal_file EXPECTED OUTPUT
685
686
687 test_begin_subtest "notmuch_database_get_config_list: all pairs (ndlc)"
688 cat c_head2 - c_tail <<'EOF' | test_C ${MAIL_DIR} ${NOTMUCH_CONFIG} %NULL%
689 {
690    notmuch_config_list_t *list;
691    EXPECT0(notmuch_database_get_config_list (db, "", &list));
692    for (; notmuch_config_list_valid (list); notmuch_config_list_move_to_next (list)) {
693       printf("%s %s\n", notmuch_config_list_key (list), notmuch_config_list_value(list));
694    }
695    notmuch_config_list_destroy (list);
696 }
697 EOF
698 cat <<'EOF' >EXPECTED
699 == stdout ==
700 aaabefore beforeval
701 key with spaces value, with, spaces!
702 test.key1 testvalue1
703 test.key2 testvalue2
704 zzzafter afterval
705 == stderr ==
706 EOF
707 test_expect_equal_file EXPECTED OUTPUT
708
709 test_begin_subtest "notmuch_database_get_config_list: one prefix (ndlc)"
710 cat c_head2 - c_tail <<'EOF' | test_C ${MAIL_DIR} ${NOTMUCH_CONFIG} %NULL%
711 {
712    notmuch_config_list_t *list;
713    EXPECT0(notmuch_database_get_config_list (db, "test.key", &list));
714    for (; notmuch_config_list_valid (list); notmuch_config_list_move_to_next (list)) {
715       printf("%s %s\n", notmuch_config_list_key (list), notmuch_config_list_value(list));
716    }
717    notmuch_config_list_destroy (list);
718 }
719 EOF
720 cat <<'EOF' >EXPECTED
721 == stdout ==
722 test.key1 testvalue1
723 test.key2 testvalue2
724 == stderr ==
725 EOF
726 test_expect_equal_file EXPECTED OUTPUT
727
728 test_begin_subtest "list by keys (ndlc)"
729 notmuch config set search.exclude_tags "foo;bar;fub"
730 notmuch config set new.ignore "sekrit_junk"
731 cat c_head2 - c_tail <<'EOF' | test_C ${MAIL_DIR} %NULL% %NULL%
732 {
733     notmuch_config_key_t key;
734     for (key = NOTMUCH_CONFIG_FIRST;
735          key < NOTMUCH_CONFIG_LAST;
736          key = (notmuch_config_key_t)(key + 1)) {
737         const char *val = notmuch_config_get (db, key);
738         printf("%02d: '%s'\n", key, val ? val : "NULL" );
739     }
740 }
741 EOF
742 cat <<'EOF' >EXPECTED
743 == stdout ==
744 00: 'MAIL_DIR'
745 01: 'MAIL_DIR'
746 02: 'MAIL_DIR/.notmuch/hooks'
747 03: 'MAIL_DIR/.notmuch/backups'
748 04: 'foo;bar;fub'
749 05: 'unread;inbox'
750 06: 'sekrit_junk'
751 07: 'true'
752 08: 'test_suite@notmuchmail.org'
753 09: 'test_suite_other@notmuchmail.org;test_suite@otherdomain.org'
754 10: 'Notmuch Test Suite'
755 11: '8000'
756 == stderr ==
757 EOF
758 test_expect_equal_file EXPECTED OUTPUT
759
760 test_begin_subtest "load default values (ndlc, nonexistent config)"
761 cat c_head2 - c_tail <<'EOF' | test_C ${MAIL_DIR} /nonexistent %NULL%
762 {
763     notmuch_config_key_t key;
764     for (key = NOTMUCH_CONFIG_FIRST;
765          key < NOTMUCH_CONFIG_LAST;
766          key = (notmuch_config_key_t)(key + 1)) {
767         const char *val = notmuch_config_get (db, key);
768         printf("%02d: '%s'\n", key, val ? val : "NULL" );
769     }
770 }
771 EOF
772
773 _libconfig_sanitize < OUTPUT > OUTPUT.clean
774
775 cat <<'EOF' >EXPECTED
776 == stdout ==
777 00: 'MAIL_DIR'
778 01: 'MAIL_DIR'
779 02: 'MAIL_DIR/.notmuch/hooks'
780 03: 'MAIL_DIR/.notmuch/backups'
781 04: ''
782 05: 'unread;inbox'
783 06: ''
784 07: 'true'
785 08: 'USERNAME@localhost'
786 09: 'NULL'
787 10: 'USER_FULL_NAME'
788 11: '8000'
789 == stderr ==
790 EOF
791 test_expect_equal_file EXPECTED OUTPUT.clean
792
793 backup_database
794 test_begin_subtest "override config from \${HOME}/.notmuch-config (ndlc)"
795 ovconfig=${HOME}/.notmuch-config
796 cp ${NOTMUCH_CONFIG} ${ovconfig}
797 old_NOTMUCH_CONFIG=${NOTMUCH_CONFIG}
798 unset NOTMUCH_CONFIG
799 notmuch --config=${ovconfig} config set test.key1 overridden-home
800 cat c_head2 - c_tail <<'EOF' | test_C ${MAIL_DIR} %NULL% %NULL%
801 {
802    EXPECT0(notmuch_database_get_config (db, "test.key1", &val));
803    printf("test.key1 = %s\n", val);
804    EXPECT0(notmuch_database_get_config (db, "test.key2", &val));
805    printf("test.key2 = %s\n", val);
806 }
807 EOF
808 rm -f ${ovconfig}
809 export NOTMUCH_CONFIG=${old_NOTMUCH_CONFIG}
810 cat <<'EOF' >EXPECTED
811 == stdout ==
812 test.key1 = overridden-home
813 test.key2 = testvalue2
814 == stderr ==
815 EOF
816 test_expect_equal_file EXPECTED OUTPUT
817 restore_database
818
819 test_begin_subtest "notmuch_config_get_pairs: prefix (ndlc)"
820 cat c_head2 - c_tail <<'EOF' | test_C ${MAIL_DIR} ${NOTMUCH_CONFIG} %NULL%
821 {
822    notmuch_config_pairs_t *list;
823    for (list =  notmuch_config_get_pairs (db, "user.");
824         notmuch_config_pairs_valid (list);
825         notmuch_config_pairs_move_to_next (list)) {
826      printf("%s %s\n", notmuch_config_pairs_key (list), notmuch_config_pairs_value(list));
827    }
828    notmuch_config_pairs_destroy (list);
829 }
830 EOF
831 cat <<'EOF' >EXPECTED
832 == stdout ==
833 user.name Notmuch Test Suite
834 user.other_email test_suite_other@notmuchmail.org;test_suite@otherdomain.org
835 user.primary_email test_suite@notmuchmail.org
836 == stderr ==
837 EOF
838 test_expect_equal_file EXPECTED OUTPUT
839
840 test_begin_subtest "notmuch_config_get_pairs: all pairs (ndlc)"
841 cat c_head2 - c_tail <<'EOF' | test_C ${MAIL_DIR} ${NOTMUCH_CONFIG} %NULL%
842 {
843    notmuch_config_pairs_t *list;
844    for (list =  notmuch_config_get_pairs (db, "");
845         notmuch_config_pairs_valid (list);
846         notmuch_config_pairs_move_to_next (list)) {
847      printf("%s %s\n", notmuch_config_pairs_key (list), notmuch_config_pairs_value(list));
848    }
849    notmuch_config_pairs_destroy (list);
850 }
851 EOF
852 cat <<'EOF' >EXPECTED
853 == stdout ==
854 aaabefore beforeval
855 database.autocommit 8000
856 database.backup_dir MAIL_DIR/.notmuch/backups
857 database.hook_dir MAIL_DIR/.notmuch/hooks
858 database.mail_root MAIL_DIR
859 database.path MAIL_DIR
860 key with spaces value, with, spaces!
861 maildir.synchronize_flags true
862 new.ignore sekrit_junk
863 new.tags unread;inbox
864 search.exclude_tags foo;bar;fub
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 notmuch config set database.path ${MAIL_DIR}/nonexistent
980 cat c_head3 - c_tail3 <<'EOF' | test_C ${MAIL_DIR}
981   const char *path = NULL;
982   notmuch_status_t st = notmuch_database_open_with_config(argv[1],
983                                                           NOTMUCH_DATABASE_MODE_READ_ONLY,
984                                                           NULL, NULL, &db, NULL);
985   printf ("status: %d\n", st);
986   path = notmuch_database_get_path (db);
987   printf ("path: %s\n", path ? path : "(null)");
988 EOF
989 cat <<EOF> EXPECTED
990 == stdout ==
991 status: 0
992 path: MAIL_DIR
993 db == NULL: 0
994 == stderr ==
995 EOF
996 notmuch_dir_sanitize < OUTPUT > OUTPUT.clean
997 test_expect_equal_file EXPECTED OUTPUT.clean
998
999 test_done