]> git.notmuchmail.org Git - notmuch/blob - test/T590-libconfig.sh
test: known broken tests for leading/trailing ws in config
[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 test_subtest_known_broken
277 cat c_head - c_tail <<'EOF' | test_C ${MAIL_DIR} ${NOTMUCH_CONFIG} %NULL%
278 {
279     notmuch_config_values_t *values;
280     EXPECT0(notmuch_config_set (db, NOTMUCH_CONFIG_NEW_TAGS, " a ; b c ; d "));
281     for (values = notmuch_config_get_values (db, NOTMUCH_CONFIG_NEW_TAGS);
282          notmuch_config_values_valid (values);
283          notmuch_config_values_move_to_next (values))
284     {
285           puts (notmuch_config_values_get (values));
286     }
287 }
288 EOF
289 cat <<'EOF' >EXPECTED
290 == stdout ==
291 a
292 b c
293 d
294 == stderr ==
295 EOF
296 test_expect_equal_file EXPECTED OUTPUT
297 restore_database
298
299 test_begin_subtest "notmuch_config_get_values_string"
300 cat c_head - c_tail <<'EOF' | test_C ${MAIL_DIR} ${NOTMUCH_CONFIG} %NULL%
301 {
302     notmuch_config_values_t *values;
303     EXPECT0(notmuch_database_set_config (db, "test.list", "x;y;z"));
304     for (values = notmuch_config_get_values_string (db, "test.list");
305          notmuch_config_values_valid (values);
306          notmuch_config_values_move_to_next (values))
307     {
308           puts (notmuch_config_values_get (values));
309     }
310 }
311 EOF
312 cat <<'EOF' >EXPECTED
313 == stdout ==
314 x
315 y
316 z
317 == stderr ==
318 EOF
319 test_expect_equal_file EXPECTED OUTPUT
320 restore_database
321
322 test_begin_subtest "notmuch_config_get_values (restart)"
323 cat c_head - c_tail <<'EOF' | test_C ${MAIL_DIR} ${NOTMUCH_CONFIG} %NULL%
324 {
325     notmuch_config_values_t *values;
326     EXPECT0(notmuch_config_set (db, NOTMUCH_CONFIG_NEW_TAGS, "a;b;c"));
327     for (values = notmuch_config_get_values (db, NOTMUCH_CONFIG_NEW_TAGS);
328          notmuch_config_values_valid (values);
329          notmuch_config_values_move_to_next (values))
330     {
331           puts (notmuch_config_values_get (values));
332     }
333     for (notmuch_config_values_start (values);
334          notmuch_config_values_valid (values);
335          notmuch_config_values_move_to_next (values))
336     {
337           puts (notmuch_config_values_get (values));
338     }
339 }
340 EOF
341 cat <<'EOF' >EXPECTED
342 == stdout ==
343 a
344 b
345 c
346 a
347 b
348 c
349 == stderr ==
350 EOF
351 test_expect_equal_file EXPECTED OUTPUT
352 restore_database
353
354 backup_database
355 test_begin_subtest "notmuch_config_get_values, trailing ;"
356 cat c_head - c_tail <<'EOF' | test_C ${MAIL_DIR} ${NOTMUCH_CONFIG} %NULL%
357 {
358     notmuch_config_values_t *values;
359     EXPECT0(notmuch_config_set (db, NOTMUCH_CONFIG_NEW_TAGS, "a;b;c"));
360     for (values = notmuch_config_get_values (db, NOTMUCH_CONFIG_NEW_TAGS);
361          notmuch_config_values_valid (values);
362          notmuch_config_values_move_to_next (values))
363     {
364           puts (notmuch_config_values_get (values));
365     }
366 }
367 EOF
368 cat <<'EOF' >EXPECTED
369 == stdout ==
370 a
371 b
372 c
373 == stderr ==
374 EOF
375 test_expect_equal_file EXPECTED OUTPUT
376 restore_database
377
378 backup_database
379 test_begin_subtest "get config by key"
380 cat c_head - c_tail <<'EOF' | test_C ${MAIL_DIR} ${NOTMUCH_CONFIG}
381 {
382    printf("before = %s\n", notmuch_config_get (db, NOTMUCH_CONFIG_SYNC_MAILDIR_FLAGS));
383    EXPECT0(notmuch_database_set_config (db, "maildir.synchronize_flags", "false"));
384    printf("after = %s\n", notmuch_config_get (db, NOTMUCH_CONFIG_SYNC_MAILDIR_FLAGS));
385 }
386 EOF
387 cat <<'EOF' >EXPECTED
388 == stdout ==
389 before = true
390 after = false
391 == stderr ==
392 EOF
393 test_expect_equal_file EXPECTED OUTPUT
394 restore_database
395
396 backup_database
397 test_begin_subtest "set config by key"
398 notmuch config set test.key1 overridden
399 cat c_head - c_tail <<'EOF' | test_C ${MAIL_DIR} ${NOTMUCH_CONFIG}
400 {
401    printf("before = %s\n", notmuch_config_get (db, NOTMUCH_CONFIG_SYNC_MAILDIR_FLAGS));
402    EXPECT0(notmuch_config_set (db, NOTMUCH_CONFIG_SYNC_MAILDIR_FLAGS, "false"));
403    printf("after = %s\n", notmuch_config_get (db, NOTMUCH_CONFIG_SYNC_MAILDIR_FLAGS));
404 }
405 EOF
406 cat <<'EOF' >EXPECTED
407 == stdout ==
408 before = true
409 after = false
410 == stderr ==
411 EOF
412 test_expect_equal_file EXPECTED OUTPUT
413 restore_database
414
415 test_begin_subtest "load default values"
416 export MAILDIR=${MAIL_DIR}
417 cat c_head - c_tail <<'EOF' | test_C ${MAIL_DIR} '' %NULL%
418 {
419     notmuch_config_key_t key;
420     for (key = NOTMUCH_CONFIG_FIRST;
421          key < NOTMUCH_CONFIG_LAST;
422          key = (notmuch_config_key_t)(key + 1)) {
423         const char *val = notmuch_config_get (db, key);
424         printf("%02d: '%s'\n", key, val ? val : "NULL" );
425     }
426 }
427 EOF
428
429 _libconfig_sanitize < OUTPUT > OUTPUT.clean
430
431 cat <<'EOF' >EXPECTED
432 == stdout ==
433 00: 'MAIL_DIR'
434 01: 'MAIL_DIR'
435 02: 'MAIL_DIR/.notmuch/hooks'
436 03: 'MAIL_DIR/.notmuch/backups'
437 04: ''
438 05: 'unread;inbox'
439 06: ''
440 07: 'true'
441 08: 'USERNAME@localhost'
442 09: 'NULL'
443 10: 'USER_FULL_NAME'
444 11: '8000'
445 == stderr ==
446 EOF
447 unset MAILDIR
448 test_expect_equal_file EXPECTED OUTPUT.clean
449
450 backup_database
451 test_begin_subtest "override config from \${NOTMUCH_CONFIG}"
452 notmuch config set test.key1 overridden
453 # second argument omitted to make argv[2] == NULL
454 cat c_head - c_tail <<'EOF' | test_C ${MAIL_DIR}
455 {
456    EXPECT0(notmuch_database_get_config (db, "test.key1", &val));
457    printf("test.key1 = %s\n", val);
458    EXPECT0(notmuch_database_get_config (db, "test.key2", &val));
459    printf("test.key2 = %s\n", val);
460 }
461 EOF
462 notmuch config set test.key1
463 cat <<'EOF' >EXPECTED
464 == stdout ==
465 test.key1 = overridden
466 test.key2 = testvalue2
467 == stderr ==
468 EOF
469 test_expect_equal_file EXPECTED OUTPUT
470 restore_database
471
472 backup_database
473 test_begin_subtest "override config from \${HOME}/.notmuch-config"
474 ovconfig=${HOME}/.notmuch-config
475 cp ${NOTMUCH_CONFIG} ${ovconfig}
476 old_NOTMUCH_CONFIG=${NOTMUCH_CONFIG}
477 unset NOTMUCH_CONFIG
478 notmuch --config=${ovconfig} config set test.key1 overridden-home
479 cat c_head - c_tail <<'EOF' | test_C ${MAIL_DIR} %NULL% %NULL%
480 {
481    EXPECT0(notmuch_database_get_config (db, "test.key1", &val));
482    printf("test.key1 = %s\n", val);
483    EXPECT0(notmuch_database_get_config (db, "test.key2", &val));
484    printf("test.key2 = %s\n", val);
485 }
486 EOF
487 rm -f ${ovconfig}
488 export NOTMUCH_CONFIG=${old_NOTMUCH_CONFIG}
489 cat <<'EOF' >EXPECTED
490 == stdout ==
491 test.key1 = overridden-home
492 test.key2 = testvalue2
493 == stderr ==
494 EOF
495 test_expect_equal_file EXPECTED OUTPUT
496 restore_database
497
498 backup_database
499 test_begin_subtest "override config from \${XDG_CONFIG_HOME}/notmuch"
500 ovconfig=${HOME}/.config/notmuch/default/config
501 mkdir -p $(dirname ${ovconfig})
502 cp ${NOTMUCH_CONFIG} ${ovconfig}
503 old_NOTMUCH_CONFIG=${NOTMUCH_CONFIG}
504 unset NOTMUCH_CONFIG
505 notmuch --config=${ovconfig} config set test.key1 overridden-xdg
506 cat c_head - c_tail <<'EOF' | test_C ${MAIL_DIR} %NULL% %NULL%
507 {
508    EXPECT0(notmuch_database_get_config (db, "test.key1", &val));
509    printf("test.key1 = %s\n", val);
510    EXPECT0(notmuch_database_get_config (db, "test.key2", &val));
511    printf("test.key2 = %s\n", val);
512 }
513 EOF
514 rm -f ${ovconfig}
515 export NOTMUCH_CONFIG=${old_NOTMUCH_CONFIG}
516 cat <<'EOF' >EXPECTED
517 == stdout ==
518 test.key1 = overridden-xdg
519 test.key2 = testvalue2
520 == stderr ==
521 EOF
522 test_expect_equal_file EXPECTED OUTPUT
523 restore_database
524
525 backup_database
526 test_begin_subtest "override config from \${XDG_CONFIG_HOME}/notmuch with profile"
527 ovconfig=${HOME}/.config/notmuch/work/config
528 mkdir -p $(dirname ${ovconfig})
529 cp ${NOTMUCH_CONFIG} ${ovconfig}
530 old_NOTMUCH_CONFIG=${NOTMUCH_CONFIG}
531 unset NOTMUCH_CONFIG
532 notmuch --config=${ovconfig} config set test.key1 overridden-xdg-profile
533 cat c_head - c_tail <<'EOF' | test_C ${MAIL_DIR} %NULL% work
534 {
535    EXPECT0(notmuch_database_get_config (db, "test.key1", &val));
536    printf("test.key1 = %s\n", val);
537    EXPECT0(notmuch_database_get_config (db, "test.key2", &val));
538    printf("test.key2 = %s\n", val);
539 }
540 EOF
541 rm -f ${ovconfig}
542 export NOTMUCH_CONFIG=${old_NOTMUCH_CONFIG}
543 cat <<'EOF' >EXPECTED
544 == stdout ==
545 test.key1 = overridden-xdg-profile
546 test.key2 = testvalue2
547 == stderr ==
548 EOF
549 test_expect_equal_file EXPECTED OUTPUT
550 restore_database
551
552 backup_database
553 test_begin_subtest "override config from \${HOME}/.notmuch-config.work (via args)"
554 ovconfig=${HOME}/.notmuch-config.work
555 cp ${NOTMUCH_CONFIG} ${ovconfig}
556 old_NOTMUCH_CONFIG=${NOTMUCH_CONFIG}
557 unset NOTMUCH_CONFIG
558 notmuch --config=${ovconfig} config set test.key1 overridden-profile
559 cat c_head - c_tail <<'EOF' | test_C ${MAIL_DIR} %NULL% work
560 {
561    EXPECT0(notmuch_database_get_config (db, "test.key1", &val));
562    printf("test.key1 = %s\n", val);
563    EXPECT0(notmuch_database_get_config (db, "test.key2", &val));
564    printf("test.key2 = %s\n", val);
565 }
566 EOF
567 #rm -f ${ovconfig}
568 export NOTMUCH_CONFIG=${old_NOTMUCH_CONFIG}
569 cat <<'EOF' >EXPECTED
570 == stdout ==
571 test.key1 = overridden-profile
572 test.key2 = testvalue2
573 == stderr ==
574 EOF
575 test_expect_equal_file EXPECTED OUTPUT
576 restore_database
577
578 test_begin_subtest "no config, fail to open database"
579 old_NOTMUCH_CONFIG=${NOTMUCH_CONFIG}
580 unset NOTMUCH_CONFIG
581 cat c_head - c_tail <<'EOF' | test_C %NULL% '' %NULL%
582 {
583    printf("NOT RUN");
584 }
585 EOF
586 export NOTMUCH_CONFIG=${old_NOTMUCH_CONFIG}
587 cat <<'EOF' >EXPECTED
588 == stdout ==
589 == stderr ==
590 error opening database
591 No database found
592 Error: could not locate database.
593
594 EOF
595 test_expect_equal_file EXPECTED OUTPUT
596
597 test_begin_subtest "open database from NOTMUCH_DATABASE"
598 old_NOTMUCH_CONFIG=${NOTMUCH_CONFIG}
599 unset NOTMUCH_CONFIG
600 export NOTMUCH_DATABASE=${MAIL_DIR}
601 cat c_head - c_tail <<'EOF' | test_C %NULL% '' %NULL%
602 {
603    EXPECT0(notmuch_database_get_config (db, "test.key1", &val));
604    printf("test.key1 = %s\n", val);
605    EXPECT0(notmuch_database_get_config (db, "test.key2", &val));
606    printf("test.key2 = %s\n", val);
607 }
608 EOF
609 export NOTMUCH_CONFIG=${old_NOTMUCH_CONFIG}
610 unset NOTMUCH_DATABASE
611 cat <<'EOF' >EXPECTED
612 == stdout ==
613 test.key1 = testvalue1
614 test.key2 = testvalue2
615 == stderr ==
616 EOF
617 test_expect_equal_file EXPECTED OUTPUT
618
619 test_begin_subtest "NOTMUCH_DATABASE overrides config"
620 cp notmuch-config notmuch-config.bak
621 notmuch config set database.path /nonexistent
622 export NOTMUCH_DATABASE=${MAIL_DIR}
623 cat c_head - c_tail <<'EOF' | test_C %NULL% '' %NULL%
624 {
625    EXPECT0(notmuch_database_get_config (db, "test.key1", &val));
626    printf("test.key1 = %s\n", val);
627    EXPECT0(notmuch_database_get_config (db, "test.key2", &val));
628    printf("test.key2 = %s\n", val);
629 }
630 EOF
631 export NOTMUCH_CONFIG=${old_NOTMUCH_CONFIG}
632 unset NOTMUCH_DATABASE
633 cat <<'EOF' >EXPECTED
634 == stdout ==
635 test.key1 = testvalue1
636 test.key2 = testvalue2
637 == stderr ==
638 EOF
639 cp notmuch-config.bak notmuch-config
640 test_expect_equal_file EXPECTED OUTPUT
641
642 cat <<EOF > c_head2
643 #include <string.h>
644 #include <stdlib.h>
645 #include <notmuch-test.h>
646
647 int main (int argc, char** argv)
648 {
649    notmuch_database_t *db;
650    char *val;
651    notmuch_status_t stat;
652    char *msg = NULL;
653
654    for (int i = 1; i < argc; i++)
655       if (strcmp (argv[i], "%NULL%") == 0) argv[i] = NULL;
656
657    stat = notmuch_database_load_config (argv[1],
658                                         argv[2],
659                                         argv[3],
660                                         &db,
661                                         &msg);
662    if (stat != NOTMUCH_STATUS_SUCCESS  && stat != NOTMUCH_STATUS_NO_CONFIG) {
663      fprintf (stderr, "error opening database\n%d: %s\n%s\n", stat,
664               notmuch_status_to_string (stat), msg ? msg : "");
665      exit (1);
666    }
667 EOF
668
669
670 test_begin_subtest "notmuch_database_get_config (ndlc)"
671 cat c_head2 - c_tail <<'EOF' | test_C ${MAIL_DIR} %NULL% %NULL%
672 {
673    EXPECT0(notmuch_database_get_config (db, "test.key1", &val));
674    printf("test.key1 = %s\n", val);
675    EXPECT0(notmuch_database_get_config (db, "test.key2", &val));
676    printf("test.key2 = %s\n", val);
677 }
678 EOF
679 cat <<'EOF' >EXPECTED
680 == stdout ==
681 test.key1 = testvalue1
682 test.key2 = testvalue2
683 == stderr ==
684 EOF
685 test_expect_equal_file EXPECTED OUTPUT
686
687
688 test_begin_subtest "notmuch_database_get_config_list: all pairs (ndlc)"
689 cat c_head2 - c_tail <<'EOF' | test_C ${MAIL_DIR} ${NOTMUCH_CONFIG} %NULL%
690 {
691    notmuch_config_list_t *list;
692    EXPECT0(notmuch_database_get_config_list (db, "", &list));
693    for (; notmuch_config_list_valid (list); notmuch_config_list_move_to_next (list)) {
694       printf("%s %s\n", notmuch_config_list_key (list), notmuch_config_list_value(list));
695    }
696    notmuch_config_list_destroy (list);
697 }
698 EOF
699 cat <<'EOF' >EXPECTED
700 == stdout ==
701 aaabefore beforeval
702 key with spaces value, with, spaces!
703 test.key1 testvalue1
704 test.key2 testvalue2
705 zzzafter afterval
706 == stderr ==
707 EOF
708 test_expect_equal_file EXPECTED OUTPUT
709
710 test_begin_subtest "notmuch_database_get_config_list: one prefix (ndlc)"
711 cat c_head2 - c_tail <<'EOF' | test_C ${MAIL_DIR} ${NOTMUCH_CONFIG} %NULL%
712 {
713    notmuch_config_list_t *list;
714    EXPECT0(notmuch_database_get_config_list (db, "test.key", &list));
715    for (; notmuch_config_list_valid (list); notmuch_config_list_move_to_next (list)) {
716       printf("%s %s\n", notmuch_config_list_key (list), notmuch_config_list_value(list));
717    }
718    notmuch_config_list_destroy (list);
719 }
720 EOF
721 cat <<'EOF' >EXPECTED
722 == stdout ==
723 test.key1 testvalue1
724 test.key2 testvalue2
725 == stderr ==
726 EOF
727 test_expect_equal_file EXPECTED OUTPUT
728
729 test_begin_subtest "list by keys (ndlc)"
730 notmuch config set search.exclude_tags "foo;bar;fub"
731 notmuch config set new.ignore "sekrit_junk"
732 cat c_head2 - c_tail <<'EOF' | test_C ${MAIL_DIR} %NULL% %NULL%
733 {
734     notmuch_config_key_t key;
735     for (key = NOTMUCH_CONFIG_FIRST;
736          key < NOTMUCH_CONFIG_LAST;
737          key = (notmuch_config_key_t)(key + 1)) {
738         const char *val = notmuch_config_get (db, key);
739         printf("%02d: '%s'\n", key, val ? val : "NULL" );
740     }
741 }
742 EOF
743 cat <<'EOF' >EXPECTED
744 == stdout ==
745 00: 'MAIL_DIR'
746 01: 'MAIL_DIR'
747 02: 'MAIL_DIR/.notmuch/hooks'
748 03: 'MAIL_DIR/.notmuch/backups'
749 04: 'foo;bar;fub'
750 05: 'unread;inbox'
751 06: 'sekrit_junk'
752 07: 'true'
753 08: 'test_suite@notmuchmail.org'
754 09: 'test_suite_other@notmuchmail.org;test_suite@otherdomain.org'
755 10: 'Notmuch Test Suite'
756 11: '8000'
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 == stderr ==
791 EOF
792 test_expect_equal_file EXPECTED OUTPUT.clean
793
794 backup_database
795 test_begin_subtest "override config from \${HOME}/.notmuch-config (ndlc)"
796 ovconfig=${HOME}/.notmuch-config
797 cp ${NOTMUCH_CONFIG} ${ovconfig}
798 old_NOTMUCH_CONFIG=${NOTMUCH_CONFIG}
799 unset NOTMUCH_CONFIG
800 notmuch --config=${ovconfig} config set test.key1 overridden-home
801 cat c_head2 - c_tail <<'EOF' | test_C ${MAIL_DIR} %NULL% %NULL%
802 {
803    EXPECT0(notmuch_database_get_config (db, "test.key1", &val));
804    printf("test.key1 = %s\n", val);
805    EXPECT0(notmuch_database_get_config (db, "test.key2", &val));
806    printf("test.key2 = %s\n", val);
807 }
808 EOF
809 rm -f ${ovconfig}
810 export NOTMUCH_CONFIG=${old_NOTMUCH_CONFIG}
811 cat <<'EOF' >EXPECTED
812 == stdout ==
813 test.key1 = overridden-home
814 test.key2 = testvalue2
815 == stderr ==
816 EOF
817 test_expect_equal_file EXPECTED OUTPUT
818 restore_database
819
820 test_begin_subtest "notmuch_config_get_pairs: prefix (ndlc)"
821 cat c_head2 - c_tail <<'EOF' | test_C ${MAIL_DIR} ${NOTMUCH_CONFIG} %NULL%
822 {
823    notmuch_config_pairs_t *list;
824    for (list =  notmuch_config_get_pairs (db, "user.");
825         notmuch_config_pairs_valid (list);
826         notmuch_config_pairs_move_to_next (list)) {
827      printf("%s %s\n", notmuch_config_pairs_key (list), notmuch_config_pairs_value(list));
828    }
829    notmuch_config_pairs_destroy (list);
830 }
831 EOF
832 cat <<'EOF' >EXPECTED
833 == stdout ==
834 user.name Notmuch Test Suite
835 user.other_email test_suite_other@notmuchmail.org;test_suite@otherdomain.org
836 user.primary_email test_suite@notmuchmail.org
837 == stderr ==
838 EOF
839 test_expect_equal_file EXPECTED OUTPUT
840
841 test_begin_subtest "notmuch_config_get_pairs: all pairs (ndlc)"
842 cat c_head2 - c_tail <<'EOF' | test_C ${MAIL_DIR} ${NOTMUCH_CONFIG} %NULL%
843 {
844    notmuch_config_pairs_t *list;
845    for (list =  notmuch_config_get_pairs (db, "");
846         notmuch_config_pairs_valid (list);
847         notmuch_config_pairs_move_to_next (list)) {
848      printf("%s %s\n", notmuch_config_pairs_key (list), notmuch_config_pairs_value(list));
849    }
850    notmuch_config_pairs_destroy (list);
851 }
852 EOF
853 cat <<'EOF' >EXPECTED
854 == stdout ==
855 aaabefore beforeval
856 database.autocommit 8000
857 database.backup_dir MAIL_DIR/.notmuch/backups
858 database.hook_dir MAIL_DIR/.notmuch/hooks
859 database.mail_root MAIL_DIR
860 database.path MAIL_DIR
861 key with spaces value, with, spaces!
862 maildir.synchronize_flags true
863 new.ignore sekrit_junk
864 new.tags unread;inbox
865 search.exclude_tags foo;bar;fub
866 test.key1 testvalue1
867 test.key2 testvalue2
868 user.name Notmuch Test Suite
869 user.other_email test_suite_other@notmuchmail.org;test_suite@otherdomain.org
870 user.primary_email test_suite@notmuchmail.org
871 zzzafter afterval
872 == stderr ==
873 EOF
874 test_expect_equal_file EXPECTED OUTPUT
875
876 cat <<EOF > c_head3
877 #include <notmuch-test.h>
878 int main (int argc, char **argv) {
879   notmuch_status_t stat;
880   notmuch_database_t *db = NULL;
881 EOF
882
883 cat <<EOF > c_tail3
884   printf("db == NULL: %d\n", db == NULL);
885 }
886 EOF
887
888 test_begin_subtest "open: database set to null on missing config"
889 cat c_head3 - c_tail3 <<'EOF' | test_C ${MAIL_DIR}
890   notmuch_status_t st = notmuch_database_open_with_config(argv[1],
891                                                           NOTMUCH_DATABASE_MODE_READ_ONLY,
892                                                           "/nonexistent", NULL, &db, NULL);
893 EOF
894 cat <<EOF> EXPECTED
895 == stdout ==
896 db == NULL: 1
897 == stderr ==
898 EOF
899 test_expect_equal_file EXPECTED OUTPUT
900
901 test_begin_subtest "open: database set to null on missing config (env)"
902 old_NOTMUCH_CONFIG=${NOTMUCH_CONFIG}
903 export NOTMUCH_CONFIG="/nonexistent"
904 cat c_head3 - c_tail3 <<'EOF' | test_C ${MAIL_DIR}
905   notmuch_status_t st = notmuch_database_open_with_config(argv[1],
906                                                           NOTMUCH_DATABASE_MODE_READ_ONLY,
907                                                           NULL, NULL, &db, NULL);
908 EOF
909 export NOTMUCH_CONFIG=${old_NOTMUCH_CONFIG}
910 cat <<EOF> EXPECTED
911 == stdout ==
912 db == NULL: 1
913 == stderr ==
914 EOF
915 test_expect_equal_file EXPECTED OUTPUT
916
917 test_begin_subtest "create: database set to null on missing config"
918 cat c_head3 - c_tail3 <<'EOF' | test_C ${MAIL_DIR} "/nonexistent"
919   notmuch_status_t st = notmuch_database_create_with_config(argv[1],argv[2], NULL, &db, NULL);
920 EOF
921 cat <<EOF> EXPECTED
922 == stdout ==
923 db == NULL: 1
924 == stderr ==
925 EOF
926 test_expect_equal_file EXPECTED OUTPUT
927
928 test_begin_subtest "create: database set to null on missing config (env)"
929 old_NOTMUCH_CONFIG=${NOTMUCH_CONFIG}
930 export NOTMUCH_CONFIG="/nonexistent"
931 cat c_head3 - c_tail3 <<'EOF' | test_C ${MAIL_DIR}
932   notmuch_status_t st = notmuch_database_create_with_config(argv[1],
933                                                           NULL, NULL, &db, NULL);
934 EOF
935 export NOTMUCH_CONFIG=${old_NOTMUCH_CONFIG}
936 cat <<EOF> EXPECTED
937 == stdout ==
938 db == NULL: 1
939 == stderr ==
940 EOF
941 test_expect_equal_file EXPECTED OUTPUT
942
943 test_begin_subtest "load_config: database set non-null on missing config"
944 cat c_head3 - c_tail3 <<'EOF' | test_C ${MAIL_DIR} "/nonexistent"
945   notmuch_status_t st = notmuch_database_load_config(argv[1],argv[2], NULL, &db, NULL);
946 EOF
947 cat <<EOF> EXPECTED
948 == stdout ==
949 db == NULL: 0
950 == stderr ==
951 EOF
952 test_expect_equal_file EXPECTED OUTPUT
953
954 test_begin_subtest "load_config: database non-null on missing config (env)"
955 old_NOTMUCH_CONFIG=${NOTMUCH_CONFIG}
956 export NOTMUCH_CONFIG="/nonexistent"
957 cat c_head3 - c_tail3 <<'EOF' | test_C ${MAIL_DIR}
958   notmuch_status_t st = notmuch_database_load_config(argv[1], NULL, NULL, &db, NULL);
959 EOF
960 export NOTMUCH_CONFIG=${old_NOTMUCH_CONFIG}
961 cat <<EOF> EXPECTED
962 == stdout ==
963 db == NULL: 0
964 == stderr ==
965 EOF
966 test_expect_equal_file EXPECTED OUTPUT
967
968 test_begin_subtest "load_config: database set to NULL on fatal error"
969 cat c_head3 - c_tail3 <<'EOF' | test_C
970   notmuch_status_t st = notmuch_database_load_config("relative", NULL, NULL, &db, NULL);
971 EOF
972 cat <<EOF> EXPECTED
973 == stdout ==
974 db == NULL: 1
975 == stderr ==
976 EOF
977 test_expect_equal_file EXPECTED OUTPUT
978
979 test_begin_subtest "open: database parameter overrides implicit config"
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 cat <<EOF> EXPECTED
991 == stdout ==
992 status: 0
993 path: MAIL_DIR
994 db == NULL: 0
995 == stderr ==
996 EOF
997 notmuch_dir_sanitize < OUTPUT > OUTPUT.clean
998 test_expect_equal_file EXPECTED OUTPUT.clean
999
1000 test_done