aboutsummaryrefslogtreecommitdiff
path: root/test
diff options
context:
space:
mode:
authorDavid Bremner <david@tethera.net>2022-02-15 20:53:12 -0400
committerDavid Bremner <david@tethera.net>2022-02-15 20:54:56 -0400
commitf1b2ab70c39cacb53c0b3c1d49358260a8d1818d (patch)
tree8b06d207475c256081a10ec5eb1fbd7c959610e0 /test
parentcf342d7302544532a1f66fd7a1cc42df99fcd228 (diff)
parent7b5921877e748338359a25dae578771f768183af (diff)
Merge tag '0.35' into debian/bullseye-backportsdebian/0.35-1_bpo11+1archive/debian/0.35-1_bpo11+1
notmuch 0.35 release
Diffstat (limited to 'test')
-rwxr-xr-xtest/T030-config.sh31
-rwxr-xr-xtest/T040-setup.sh7
-rwxr-xr-xtest/T050-new.sh57
-rwxr-xr-xtest/T051-new-renames.sh40
-rwxr-xr-xtest/T055-path-config.sh11
-rwxr-xr-xtest/T060-count.sh27
-rwxr-xr-xtest/T070-insert.sh12
-rwxr-xr-xtest/T081-sexpr-search.sh184
-rwxr-xr-xtest/T100-search-by-folder.sh24
-rwxr-xr-xtest/T160-json.sh42
-rwxr-xr-xtest/T170-sexp.sh14
-rwxr-xr-xtest/T310-emacs.sh27
-rwxr-xr-xtest/T350-crypto.sh19
-rwxr-xr-xtest/T370-search-folder-coherence.sh4
-rwxr-xr-xtest/T392-python-cffi-notmuch.sh48
-rwxr-xr-xtest/T440-emacs-hello.sh10
-rwxr-xr-xtest/T450-emacs-show.sh4
-rwxr-xr-xtest/T562-lib-database.sh8
-rwxr-xr-xtest/T563-lib-directory.sh8
-rwxr-xr-xtest/T564-lib-query.sh4
-rwxr-xr-xtest/T566-lib-message.sh3
-rwxr-xr-xtest/T568-lib-thread.sh3
-rwxr-xr-xtest/T590-libconfig.sh72
-rwxr-xr-xtest/T595-reopen.sh2
-rwxr-xr-xtest/T610-message-property.sh4
-rwxr-xr-xtest/T620-lock.sh3
-rwxr-xr-xtest/T640-database-modified.sh5
-rwxr-xr-xtest/T750-gzip.sh14
-rwxr-xr-xtest/T800-asan.sh39
-rw-r--r--test/emacs.expected-output/notmuch-hello-all-tags11
-rw-r--r--test/notmuch-test.h33
-rw-r--r--test/setup.expected-output/config-with-comments4
-rw-r--r--test/symbol-test.cc6
-rw-r--r--test/test-lib-emacs.sh5
-rw-r--r--test/test-lib.sh20
35 files changed, 709 insertions, 96 deletions
diff --git a/test/T030-config.sh b/test/T030-config.sh
index 3a585d1b..43bbce31 100755
--- a/test/T030-config.sh
+++ b/test/T030-config.sh
@@ -51,7 +51,7 @@ cat <<EOF > EXPECTED
built_with.compact=something
built_with.field_processor=something
built_with.retry_lock=something
-built_with.sexpr_query=something
+built_with.sexp_queries=something
database.autocommit=8000
database.mail_root=MAIL_DIR
database.path=MAIL_DIR
@@ -67,6 +67,35 @@ user.primary_email=test_suite@notmuchmail.org
EOF
test_expect_equal_file EXPECTED OUTPUT
+test_begin_subtest "Round trip config item with leading spaces"
+test_subtest_known_broken
+notmuch config set foo.bar " thing"
+output=$(notmuch config get foo.bar)
+test_expect_equal "${output}" " thing"
+
+test_begin_subtest "Round trip config item with leading tab"
+test_subtest_known_broken
+notmuch config set foo.bar " thing"
+output=$(notmuch config get foo.bar)
+test_expect_equal "${output}" " thing"
+
+test_begin_subtest "Round trip config item with embedded tab"
+notmuch config set foo.bar "thing other"
+output=$(notmuch config get foo.bar)
+test_expect_equal "${output}" "thing other"
+
+test_begin_subtest "Round trip config item with embedded backslash"
+notmuch config set foo.bar 'thing\other'
+output=$(notmuch config get foo.bar)
+test_expect_equal "${output}" "thing\other"
+
+test_begin_subtest "Round trip config item with embedded NL/CR"
+notmuch config set foo.bar 'thing
+ other'
+output=$(notmuch config get foo.bar)
+test_expect_equal "${output}" "thing
+ other"
+
test_begin_subtest "Top level --config=FILE option"
cp "${NOTMUCH_CONFIG}" alt-config
notmuch --config=alt-config config set user.name "Another Name"
diff --git a/test/T040-setup.sh b/test/T040-setup.sh
index 42c621c8..10b29ec3 100755
--- a/test/T040-setup.sh
+++ b/test/T040-setup.sh
@@ -23,6 +23,13 @@ EOF
expected_dir=$NOTMUCH_SRCDIR/test/setup.expected-output
test_expect_equal_file ${expected_dir}/config-with-comments new-notmuch-config
+test_begin_subtest "setup consistent with config-set for single items"
+# note this relies on the config state from the previous test.
+notmuch --config=new-notmuch-config config list > list.setup
+notmuch --config=new-notmuch-config config set search.exclude_tags baz
+notmuch --config=new-notmuch-config config list > list.config
+test_expect_equal_file list.setup list.config
+
test_begin_subtest "notmuch with a config but without a database suggests notmuch new"
notmuch 2>&1 | notmuch_dir_sanitize > OUTPUT
cat <<EOF > EXPECTED
diff --git a/test/T050-new.sh b/test/T050-new.sh
index 1141c1e3..6791f87c 100755
--- a/test/T050-new.sh
+++ b/test/T050-new.sh
@@ -329,6 +329,18 @@ notmuch config set new.tags "foo;;bar"
output=$(NOTMUCH_NEW --quiet 2>&1)
test_expect_equal "$output" ""
+test_begin_subtest "leading/trailing whitespace in new.tags is ignored"
+# avoid complications with leading spaces and "notmuch config"
+sed -i 's/^tags=.*$/tags= fu bar ; ; bar /' notmuch-config
+add_message
+NOTMUCH_NEW --quiet
+notmuch dump id:$gen_msg_id | sed 's/ --.*$//' > OUTPUT
+cat <<EOF >EXPECTED
+#notmuch-dump batch-tag:3 config,properties,tags
++bar +fu%20bar
+EOF
+test_expect_equal_file EXPECTED OUTPUT
+
test_begin_subtest "Tags starting with '-' in new.tags are forbidden"
notmuch config set new.tags "-foo;bar"
output=$(NOTMUCH_NEW --debug 2>&1)
@@ -339,6 +351,16 @@ test_expect_code 1 "NOTMUCH_NEW --debug 2>&1"
notmuch config set new.tags $OLDCONFIG
+test_begin_subtest ".notmuch only ignored at top level"
+generate_message '[dir]=foo/bar/.notmuch/cur' '[subject]="Do not ignore, very important"'
+NOTMUCH_NEW > OUTPUT
+notmuch search subject:Do-not-ignore | notmuch_search_sanitize >> OUTPUT
+cat <<EOF > EXPECTED
+Added 1 new message to the database.
+thread:XXX 2001-01-05 [1/1] Notmuch Test Suite; Do not ignore, very important (inbox unread)
+EOF
+test_expect_equal_file EXPECTED OUTPUT
+
test_begin_subtest "RFC822 group names are indexed"
test_subtest_known_broken
generate_message [to]="undisclosed-recipients:"
@@ -368,31 +390,26 @@ chmod u+w ${MAIL_DIR}/.notmuch/xapian/*.*
test_expect_equal "$output" "A Xapian exception occurred opening database"
-test_begin_subtest "Handle files vanishing between scandir and add_file"
+make_shim dif-shim<<EOF
+#include <notmuch-test.h>
-# A file for scandir to find. It won't get indexed, so can be empty.
-touch ${MAIL_DIR}/vanish
+WRAP_DLFUNC(notmuch_status_t, notmuch_database_index_file, \
+ (notmuch_database_t *database, const char *filename, notmuch_indexopts_t *indexopts, notmuch_message_t **message))
-# Breakpoint to remove the file before indexing
-cat <<EOF > notmuch-new-vanish.gdb
-set breakpoint pending on
-set logging file notmuch-new-vanish-gdb.log
-set logging on
-break notmuch_database_index_file
-commands
-shell rm -f ${MAIL_DIR}/vanish
-continue
-end
-run
+ if (unlink ("${MAIL_DIR}/vanish")) {
+ fprintf (stderr, "unlink failed\n");
+ exit (42);
+ }
+ return notmuch_database_index_file_orig (database, filename, indexopts, message);
+}
EOF
-${TEST_GDB} --batch-silent --return-child-result -x notmuch-new-vanish.gdb \
- --args notmuch new 2>OUTPUT 1>/dev/null
-echo "exit status: $?" >> OUTPUT
-
-# Clean up the file in case gdb isn't available.
-rm -f ${MAIL_DIR}/vanish
+test_begin_subtest "Handle files vanishing between scandir and add_file"
+# A file for scandir to find. It won't get indexed, so can be empty.
+touch ${MAIL_DIR}/vanish
+notmuch_with_shim dif-shim new 2>OUTPUT 1>/dev/null
+echo "exit status: $?" >> OUTPUT
cat <<EOF > EXPECTED
Unexpected error with file ${MAIL_DIR}/vanish
add_file: Something went wrong trying to read or write a file
diff --git a/test/T051-new-renames.sh b/test/T051-new-renames.sh
new file mode 100755
index 00000000..ebd06be1
--- /dev/null
+++ b/test/T051-new-renames.sh
@@ -0,0 +1,40 @@
+#!/usr/bin/env bash
+test_description='"notmuch new" with directory renames'
+. $(dirname "$0")/test-lib.sh || exit 1
+
+for loop in {1..10}; do
+
+rm -rf ${MAIL_DIR}
+
+for i in {1..10}; do
+ generate_message '[dir]=foo' '[subject]="Message foo $i"'
+done
+
+for i in {1..10}; do
+ generate_message '[dir]=bar' '[subject]="Message bar $i"'
+done
+
+test_begin_subtest "Index the messages, round $loop"
+output=$(NOTMUCH_NEW)
+test_expect_equal "$output" "Added 20 new messages to the database."
+
+all_files=$(notmuch search --output=files \*)
+count_foo=$(notmuch count folder:foo)
+
+test_begin_subtest "Rename folder"
+mv ${MAIL_DIR}/foo ${MAIL_DIR}/baz
+output=$(NOTMUCH_NEW)
+test_expect_equal "$output" "No new mail. Detected $count_foo file renames."
+
+test_begin_subtest "Rename folder back"
+mv ${MAIL_DIR}/baz ${MAIL_DIR}/foo
+output=$(NOTMUCH_NEW)
+test_expect_equal "$output" "No new mail. Detected $count_foo file renames."
+
+test_begin_subtest "Files remain the same"
+output=$(notmuch search --output=files \*)
+test_expect_equal "$output" "$all_files"
+
+done
+
+test_done
diff --git a/test/T055-path-config.sh b/test/T055-path-config.sh
index 6d9fb402..1df240dd 100755
--- a/test/T055-path-config.sh
+++ b/test/T055-path-config.sh
@@ -277,7 +277,7 @@ EOF
built_with.compact=something
built_with.field_processor=something
built_with.retry_lock=something
-built_with.sexpr_query=something
+built_with.sexp_queries=something
database.autocommit=8000
database.backup_dir
database.hook_dir
@@ -318,7 +318,14 @@ to=m.header('To')
print(to)
EOF
test_expect_equal_file EXPECTED OUTPUT
- ;& # fall through
+ ;;
+ *)
+ backup_database
+ test_begin_subtest ".notmuch without xapian/ handled gracefully ($config)"
+ rm -r $XAPIAN_PATH
+ test_expect_success "notmuch new"
+ restore_database
+ ;;
esac
case $config in
diff --git a/test/T060-count.sh b/test/T060-count.sh
index 6ad80df9..48146706 100755
--- a/test/T060-count.sh
+++ b/test/T060-count.sh
@@ -102,22 +102,25 @@ output=$(sed 's/^\(A Xapian exception [^:]*\):.*$/\1/' OUTPUT)
test_expect_equal "${output}" "A Xapian exception occurred opening database"
restore_database
-cat <<EOF > count-files.gdb
-set breakpoint pending on
-set logging file count-files-gdb.log
-set logging on
-break count_files
-commands
-shell cp /dev/null ${MAIL_DIR}/.notmuch/xapian/postlist.*
-continue
-end
-run
+make_shim qsm-shim<<EOF
+#include <notmuch-test.h>
+
+WRAP_DLFUNC (notmuch_status_t, notmuch_query_search_messages, (notmuch_query_t *query, notmuch_messages_t **messages))
+
+ /* XXX WARNING THIS CORRUPTS THE DATABASE */
+ int fd = open ("target_postlist", O_WRONLY|O_TRUNC);
+ if (fd < 0)
+ exit (8);
+ close (fd);
+
+ return notmuch_query_search_messages_orig(query, messages);
+}
EOF
backup_database
test_begin_subtest "error message from query_search_messages"
-${TEST_GDB} --batch-silent --return-child-result -x count-files.gdb \
- --args notmuch count --output=files '*' 2>OUTPUT 1>/dev/null
+ln -s ${MAIL_DIR}/.notmuch/xapian/postlist.* target_postlist
+notmuch_with_shim qsm-shim count --output=files '*' 2>OUTPUT 1>/dev/null
cat <<EOF > EXPECTED
notmuch count: A Xapian exception occurred
A Xapian exception occurred performing query
diff --git a/test/T070-insert.sh b/test/T070-insert.sh
index 208deb1c..ec170b30 100755
--- a/test/T070-insert.sh
+++ b/test/T070-insert.sh
@@ -234,6 +234,18 @@ output=$(notmuch show --format=json id:$gen_msg_id)
test_json_nodes <<<"$output" \
'new_tags:[0][0][0]["tags"] = ["bar", "foo"]'
+test_begin_subtest "leading/trailing whitespace in new.tags is ignored"
+# avoid complications with leading spaces and "notmuch config"
+sed -i 's/^tags=.*$/tags= fu bar ; ; bar /' notmuch-config
+gen_insert_msg
+notmuch insert < $gen_msg_filename
+notmuch dump id:$gen_msg_id | sed 's/ --.*$//' > OUTPUT
+cat <<EOF >EXPECTED
+#notmuch-dump batch-tag:3 config,properties,tags
++bar +fu%20bar
+EOF
+test_expect_equal_file EXPECTED OUTPUT
+
test_begin_subtest "Tags starting with '-' in new.tags are forbidden"
notmuch config set new.tags "-foo;bar"
gen_insert_msg
diff --git a/test/T081-sexpr-search.sh b/test/T081-sexpr-search.sh
index 2a8ad5f1..e2936cd7 100755
--- a/test/T081-sexpr-search.sh
+++ b/test/T081-sexpr-search.sh
@@ -185,6 +185,50 @@ notmuch search folder:'""' > EXPECTED
notmuch search --query=sexp '(folder "")' > OUTPUT
test_expect_equal_file EXPECTED OUTPUT
+test_begin_subtest "Search by 'folder' with --output=files"
+output=$(notmuch search --output=files --query=sexp '(folder bad/news)' | notmuch_search_files_sanitize)
+test_expect_equal "$output" "MAIL_DIR/bad/news/msg-XXX
+MAIL_DIR/duplicate/bad/news/msg-XXX"
+
+test_begin_subtest "Search by 'folder' with --output=files (trailing /)"
+output=$(notmuch search --output=files --query=sexp '(folder bad/news/)' | notmuch_search_files_sanitize)
+test_expect_equal "$output" "MAIL_DIR/bad/news/msg-XXX
+MAIL_DIR/duplicate/bad/news/msg-XXX"
+
+test_begin_subtest "Search by 'folder' (multiple)"
+output=$(notmuch search --query=sexp '(folder bad bad/news things/bad)' | notmuch_search_sanitize)
+test_expect_equal "$output" "thread:XXX 2001-01-05 [1/1] Notmuch Test Suite; To the bone (inbox unread)
+thread:XXX 2001-01-05 [1/1(2)] Notmuch Test Suite; Bears (inbox unread)
+thread:XXX 2001-01-05 [1/1] Notmuch Test Suite; Bites, stings, sad feelings (inbox unread)"
+
+test_begin_subtest "Search by 'folder' (multiple, trailing /)"
+output=$(notmuch search --query=sexp '(folder bad bad/news/ things/bad)' | notmuch_search_sanitize)
+test_expect_equal "$output" "thread:XXX 2001-01-05 [1/1] Notmuch Test Suite; To the bone (inbox unread)
+thread:XXX 2001-01-05 [1/1(2)] Notmuch Test Suite; Bears (inbox unread)
+thread:XXX 2001-01-05 [1/1] Notmuch Test Suite; Bites, stings, sad feelings (inbox unread)"
+
+test_begin_subtest "Search by 'path' with --output=files"
+output=$(notmuch search --output=files --query=sexp '(path bad/news)' | notmuch_search_files_sanitize)
+test_expect_equal "$output" "MAIL_DIR/bad/news/msg-XXX
+MAIL_DIR/duplicate/bad/news/msg-XXX"
+
+test_begin_subtest "Search by 'path' with --output=files (trailing /)"
+output=$(notmuch search --output=files --query=sexp '(path bad/news/)' | notmuch_search_files_sanitize)
+test_expect_equal "$output" "MAIL_DIR/bad/news/msg-XXX
+MAIL_DIR/duplicate/bad/news/msg-XXX"
+
+test_begin_subtest "Search by 'path' specification (multiple)"
+output=$(notmuch search --query=sexp '(path bad bad/news things/bad)' | notmuch_search_sanitize)
+test_expect_equal "$output" "thread:XXX 2001-01-05 [1/1] Notmuch Test Suite; To the bone (inbox unread)
+thread:XXX 2001-01-05 [1/1(2)] Notmuch Test Suite; Bears (inbox unread)
+thread:XXX 2001-01-05 [1/1] Notmuch Test Suite; Bites, stings, sad feelings (inbox unread)"
+
+test_begin_subtest "Search by 'path' specification (multiple, trailing /)"
+output=$(notmuch search --query=sexp '(path bad bad/news/ things/bad)' | notmuch_search_sanitize)
+test_expect_equal "$output" "thread:XXX 2001-01-05 [1/1] Notmuch Test Suite; To the bone (inbox unread)
+thread:XXX 2001-01-05 [1/1(2)] Notmuch Test Suite; Bears (inbox unread)
+thread:XXX 2001-01-05 [1/1] Notmuch Test Suite; Bites, stings, sad feelings (inbox unread)"
+
test_begin_subtest "Search by 'id'"
add_message '[subject]="search by id"' '[date]="Sat, 01 Jan 2000 12:00:00 -0000"'
output=$(notmuch search --query=sexp "(id ${gen_msg_id})" | notmuch_search_sanitize)
@@ -346,7 +390,7 @@ output=$(notmuch search --query=sexp '(attachment (starts-with not))' | notmuch_
test_expect_equal "$output" 'thread:XXX 2009-11-18 [2/2] Lars Kellogg-Stedman; [notmuch] "notmuch help" outputs to stderr? (attachment inbox signed unread)'
test_begin_subtest "starts-with, folder"
-notmuch search --output=files --query=sexp '(folder (starts-with bad))' | notmuch_dir_sanitize | sed 's/[0-9]*$/XXX/' > OUTPUT
+notmuch search --output=files --query=sexp '(folder (starts-with bad))' | notmuch_search_files_sanitize > OUTPUT
cat <<EOF > EXPECTED
MAIL_DIR/bad/msg-XXX
MAIL_DIR/bad/news/msg-XXX
@@ -768,6 +812,144 @@ notmuch search date:2009-11-18..2009-11-18 and tag:unread > EXPECTED
notmuch search --query=sexp '(and (infix "date:2009-11-18..2009-11-18") (infix "tag:unread"))' > OUTPUT
test_expect_equal_file EXPECTED OUTPUT
+test_begin_subtest "date query, empty"
+notmuch search from:keithp | notmuch_search_sanitize > EXPECTED
+notmuch search --query=sexp '(and (date) (from keithp))'| notmuch_search_sanitize > OUTPUT
+test_expect_equal_file EXPECTED OUTPUT
+
+test_begin_subtest "date query, one argument"
+notmuch search date:2009-11-18 and from:keithp | notmuch_search_sanitize > EXPECTED
+notmuch search --query=sexp '(and (date 2009-11-18) (from keithp))' | notmuch_search_sanitize > OUTPUT
+test_expect_equal_file EXPECTED OUTPUT
+
+test_begin_subtest "date query, two arguments"
+notmuch search date:2009-11-17..2009-11-18 and from:keithp | notmuch_search_sanitize > EXPECTED
+notmuch search --query=sexp '(and (date 2009-11-17 2009-11-18) (from keithp))' | notmuch_search_sanitize > OUTPUT
+test_expect_equal_file EXPECTED OUTPUT
+
+test_begin_subtest "date query, illegal nesting 1"
+notmuch search --query=sexp '(to (date))' > OUTPUT 2>&1
+cat <<EOF > EXPECTED
+notmuch search: Syntax error in query
+nested field: 'date' inside 'to'
+EOF
+test_expect_equal_file EXPECTED OUTPUT
+
+test_begin_subtest "date query, illegal nesting 2"
+notmuch search --query=sexp '(to (date 2021-11-18))' > OUTPUT 2>&1
+cat <<EOF > EXPECTED
+notmuch search: Syntax error in query
+nested field: 'date' inside 'to'
+EOF
+test_expect_equal_file EXPECTED OUTPUT
+
+test_begin_subtest "date query, illegal nesting 3"
+notmuch search --query=sexp '(date (to))' > OUTPUT 2>&1
+cat <<EOF > EXPECTED
+notmuch search: Syntax error in query
+expected atom as first argument of 'date'
+EOF
+test_expect_equal_file EXPECTED OUTPUT
+
+test_begin_subtest "date query, illegal nesting 4"
+notmuch search --query=sexp '(date today (to))' > OUTPUT 2>&1
+cat <<EOF > EXPECTED
+notmuch search: Syntax error in query
+expected atom as second argument of 'date'
+EOF
+test_expect_equal_file EXPECTED OUTPUT
+
+test_begin_subtest "date query, too many arguments"
+notmuch search --query=sexp '(date yesterday and tommorow)' > OUTPUT 2>&1
+cat <<EOF > EXPECTED
+notmuch search: Syntax error in query
+'date' expects maximum of two arguments
+EOF
+test_expect_equal_file EXPECTED OUTPUT
+
+test_begin_subtest "date query, bad date"
+notmuch search --query=sexp '(date "hawaiian-pizza-day")' > OUTPUT 2>&1
+cat <<EOF > EXPECTED
+notmuch search: Syntax error in query
+Didn't understand date specification 'hawaiian-pizza-day'
+EOF
+test_expect_equal_file EXPECTED OUTPUT
+
+test_begin_subtest "lastmod query, empty"
+notmuch search from:keithp | notmuch_search_sanitize > EXPECTED
+notmuch search --query=sexp '(and (lastmod) (from keithp))'| notmuch_search_sanitize > OUTPUT
+test_expect_equal_file EXPECTED OUTPUT
+
+test_begin_subtest "lastmod query, one argument"
+notmuch tag +4EFC743A.3060609@april.org id:4EFC743A.3060609@april.org
+revision=$(notmuch count --lastmod '*' | cut -f3)
+notmuch search lastmod:$revision..$revision | notmuch_search_sanitize > EXPECTED
+notmuch search --query=sexp "(and (lastmod $revision))" | notmuch_search_sanitize > OUTPUT
+test_expect_equal_file EXPECTED OUTPUT
+
+test_begin_subtest "lastmod query, two arguments"
+notmuch tag +keithp from:keithp
+revision2=$(notmuch count --lastmod '*' | cut -f3)
+notmuch search lastmod:$revision..$revision2 | notmuch_search_sanitize > EXPECTED
+notmuch search --query=sexp "(and (lastmod $revision $revision2))" | notmuch_search_sanitize > OUTPUT
+test_expect_equal_file EXPECTED OUTPUT
+
+test_begin_subtest "lastmod query, illegal nesting 1"
+notmuch search --query=sexp '(to (lastmod))' > OUTPUT 2>&1
+cat <<EOF > EXPECTED
+notmuch search: Syntax error in query
+nested field: 'lastmod' inside 'to'
+EOF
+test_expect_equal_file EXPECTED OUTPUT
+
+test_begin_subtest "lastmod query, bad from revision"
+notmuch search --query=sexp '(lastmod apples)' > OUTPUT 2>&1
+cat <<EOF > EXPECTED
+notmuch search: Syntax error in query
+bad 'from' revision: 'apples'
+EOF
+test_expect_equal_file EXPECTED OUTPUT
+
+test_begin_subtest "lastmod query, bad to revision"
+notmuch search --query=sexp '(lastmod 0 apples)' > OUTPUT 2>&1
+cat <<EOF > EXPECTED
+notmuch search: Syntax error in query
+bad 'to' revision: 'apples'
+EOF
+test_expect_equal_file EXPECTED OUTPUT
+
+test_begin_subtest "lastmod query, illegal nesting 2"
+notmuch search --query=sexp '(to (lastmod 2021-11-18))' > OUTPUT 2>&1
+cat <<EOF > EXPECTED
+notmuch search: Syntax error in query
+nested field: 'lastmod' inside 'to'
+EOF
+test_expect_equal_file EXPECTED OUTPUT
+
+test_begin_subtest "lastmod query, illegal nesting 3"
+notmuch search --query=sexp '(lastmod (to))' > OUTPUT 2>&1
+cat <<EOF > EXPECTED
+notmuch search: Syntax error in query
+expected atom as first argument of 'lastmod'
+EOF
+test_expect_equal_file EXPECTED OUTPUT
+
+test_begin_subtest "lastmod query, illegal nesting 4"
+notmuch search --query=sexp '(lastmod today (to))' > OUTPUT 2>&1
+cat <<EOF > EXPECTED
+notmuch search: Syntax error in query
+expected atom as second argument of 'lastmod'
+EOF
+test_expect_equal_file EXPECTED OUTPUT
+
+test_begin_subtest "lastmod query, too many arguments"
+notmuch search --query=sexp '(lastmod yesterday and tommorow)' > OUTPUT 2>&1
+cat <<EOF > EXPECTED
+notmuch search: Syntax error in query
+'lastmod' expects maximum of two arguments
+EOF
+test_expect_equal_file EXPECTED OUTPUT
+
test_begin_subtest "user header (unknown header)"
notmuch search --query=sexp '(FooBar)' >& OUTPUT
cat <<EOF > EXPECTED
diff --git a/test/T100-search-by-folder.sh b/test/T100-search-by-folder.sh
index 409cfdcc..b4f6294e 100755
--- a/test/T100-search-by-folder.sh
+++ b/test/T100-search-by-folder.sh
@@ -18,6 +18,12 @@ test_expect_equal "$output" "thread:XXX 2001-01-05 [1/1] Notmuch Test Suite; T
thread:XXX 2001-01-05 [1/1(2)] Notmuch Test Suite; Bears (inbox unread)
thread:XXX 2001-01-05 [1/1] Notmuch Test Suite; Bites, stings, sad feelings (inbox unread)"
+test_begin_subtest "search by path: specification (multiple)"
+output=$(notmuch search path:bad path:bad/news path:things/bad | notmuch_search_sanitize)
+test_expect_equal "$output" "thread:XXX 2001-01-05 [1/1] Notmuch Test Suite; To the bone (inbox unread)
+thread:XXX 2001-01-05 [1/1(2)] Notmuch Test Suite; Bears (inbox unread)
+thread:XXX 2001-01-05 [1/1] Notmuch Test Suite; Bites, stings, sad feelings (inbox unread)"
+
test_begin_subtest "Top level folder"
output=$(notmuch search folder:'""' | notmuch_search_sanitize)
test_expect_equal "$output" "thread:XXX 2001-01-05 [1/1] Notmuch Test Suite; Top level (inbox unread)"
@@ -28,8 +34,13 @@ test_expect_equal "$output" "thread:XXX 2001-01-05 [1/1(2)] Notmuch Test Suite
test_begin_subtest "Folder search with --output=files"
output=$(notmuch search --output=files folder:bad/news | notmuch_search_files_sanitize)
-test_expect_equal "$output" "MAIL_DIR/bad/news/msg-003
-MAIL_DIR/duplicate/bad/news/msg-003"
+test_expect_equal "$output" "MAIL_DIR/bad/news/msg-XXX
+MAIL_DIR/duplicate/bad/news/msg-XXX"
+
+test_begin_subtest "Folder search with --output=files (trailing /)"
+output=$(notmuch search --output=files folder:bad/news/ | notmuch_search_files_sanitize)
+test_expect_equal "$output" "MAIL_DIR/bad/news/msg-XXX
+MAIL_DIR/duplicate/bad/news/msg-XXX"
test_begin_subtest "After removing duplicate instance of matching path"
rm -r "${MAIL_DIR}/bad/news"
@@ -39,7 +50,7 @@ test_expect_equal "$output" ""
test_begin_subtest "Folder search with --output=files part #2"
output=$(notmuch search --output=files folder:duplicate/bad/news | notmuch_search_files_sanitize)
-test_expect_equal "$output" "MAIL_DIR/duplicate/bad/news/msg-003"
+test_expect_equal "$output" "MAIL_DIR/duplicate/bad/news/msg-XXX"
test_begin_subtest "After removing duplicate instance of matching path part #2"
output=$(notmuch search folder:duplicate/bad/news | notmuch_search_sanitize)
@@ -120,6 +131,13 @@ test_expect_equal "$output" "MAIL_DIR/bar/17:2,
MAIL_DIR/bar/18:2,
MAIL_DIR/cur/51:2,"
+test_begin_subtest "path: search (trailing /)"
+output=$(notmuch search --output=files path:"bar/" | notmuch_search_files_sanitize | sort)
+# cur/51:2, is a duplicate of bar/18:2,
+test_expect_equal "$output" "MAIL_DIR/bar/17:2,
+MAIL_DIR/bar/18:2,
+MAIL_DIR/cur/51:2,"
+
test_begin_subtest "top level path: search"
output=$(notmuch search --output=files path:'""' | notmuch_search_files_sanitize | sort)
test_expect_equal "$output" "MAIL_DIR/01:2,
diff --git a/test/T160-json.sh b/test/T160-json.sh
index 6a3e5812..ec7b1461 100755
--- a/test/T160-json.sh
+++ b/test/T160-json.sh
@@ -156,4 +156,46 @@ EOF
output=$(notmuch show --format=json --body=false --format-version=2 id:message-id@example.com)
test_expect_equal_json "$output" "$(cat EXPECTED)"
+test_begin_subtest "show extra headers"
+add_message "[subject]=\"extra-headers\"" "[date]=\"Sat, 01 Jan 2000 12:00:00 -0000\"" "[in-reply-to]=\"<parent@notmuch-test-suite>\"" "[body]=\"extra-headers test\""\
+ "[header]=\"Received: from mail.example.com (mail.example.com [1.1.1.1])
+ by mail.notmuchmail.org (some MTA) with ESMTP id 12345678
+ for <test_suite_other@notmuchmail.org>; Sat, 10 Apr 2010 07:54:51 -0400 (EDT)\"" \
+
+notmuch config set show.extra_headers "in-reply-to;received"
+output=$(notmuch show --format=json --body=false id:${gen_msg_id} | notmuch_json_show_sanitize)
+cat <<EOF > EXPECTED
+[
+ [
+ [
+ {
+ "crypto": {},
+ "date_relative": "2000-01-01",
+ "excluded": false,
+ "filename": [
+ "YYYYY"
+ ],
+ "headers": {
+ "Date": "Sat, 01 Jan 2000 12:00:00 +0000",
+ "From": "Notmuch Test Suite <test_suite@notmuchmail.org>",
+ "In-Reply-To": "<parent@notmuch-test-suite>",
+ "Received": "from mail.example.com (mail.example.com [1.1.1.1])\tby mail.notmuchmail.org (some MTA) with ESMTP id 12345678\tfor <test_suite_other@notmuchmail.org>; Sat, 10 Apr 2010 07:54:51 -0400 (EDT)",
+ "Subject": "extra-headers",
+ "To": "Notmuch Test Suite <test_suite@notmuchmail.org>"
+ },
+ "id": "XXXXX",
+ "match": true,
+ "tags": [
+ "inbox",
+ "unread"
+ ],
+ "timestamp": 946728000
+ },
+ []
+ ]
+ ]
+]
+EOF
+test_expect_equal_json "${output}" "$(cat EXPECTED)"
+
test_done
diff --git a/test/T170-sexp.sh b/test/T170-sexp.sh
index 18084273..0d32560c 100755
--- a/test/T170-sexp.sh
+++ b/test/T170-sexp.sh
@@ -47,4 +47,18 @@ filename=$(notmuch search --output=files "id:$id")
attachment_length=$(( $(base64 $NOTMUCH_SRCDIR/test/README | wc -c) - 1 ))
test_expect_equal "$output" "((((:id \"$id\" :match t :excluded nil :filename (\"$filename\") :timestamp 946728000 :date_relative \"2000-01-01\" :tags (\"inbox\") :body ((:id 1 :content-type \"multipart/mixed\" :content ((:id 2 :content-type \"text/plain\" :content \"This is a test message with inline attachment with a filename\") (:id 3 :content-type \"application/octet-stream\" :content-disposition \"inline\" :filename \"README\" :content-transfer-encoding \"base64\" :content-length $attachment_length)))) :crypto () :headers (:Subject \"sexp-show-inline-attachment-filename\" :From \"Notmuch Test Suite <test_suite@notmuchmail.org>\" :To \"test_suite@notmuchmail.org\" :Date \"Sat, 01 Jan 2000 12:00:00 +0000\")) ())))"
+test_begin_subtest "show extra headers"
+add_message "[subject]=\"extra-headers\"" "[date]=\"Sat, 01 Jan 2000 12:00:00 -0000\"" "[in-reply-to]=\"<parent@notmuch-test-suite>\"" "[body]=\"extra-headers test\""\
+ "[header]=\"Received: from mail.example.com (mail.example.com [1.1.1.1])
+ by mail.notmuchmail.org (some MTA) with ESMTP id 12345678
+ for <test_suite_other@notmuchmail.org>; Sat, 10 Apr 2010 07:54:51 -0400 (EDT)\"" \
+
+notmuch config set show.extra_headers "in-reply-to;received"
+notmuch show --format=sexp --body=false id:${gen_msg_id} | \
+ notmuch_dir_sanitize | sed 's/msg-[0-9]*/MSG/g'> OUTPUT
+cat <<EOF > EXPECTED
+((((:id "MSG@notmuch-test-suite" :match t :excluded nil :filename ("MAIL_DIR/MSG") :timestamp 946728000 :date_relative "2000-01-01" :tags ("inbox" "unread") :crypto () :headers (:Subject "extra-headers" :From "Notmuch Test Suite <test_suite@notmuchmail.org>" :To "Notmuch Test Suite <test_suite@notmuchmail.org>" :Date "Sat, 01 Jan 2000 12:00:00 +0000" :In-Reply-To "<parent@notmuch-test-suite>" :Received "from mail.example.com (mail.example.com [1.1.1.1])\011by mail.notmuchmail.org (some MTA) with ESMTP id 12345678\011for <test_suite_other@notmuchmail.org>; Sat, 10 Apr 2010 07:54:51 -0400 (EDT)")) ())))
+EOF
+test_expect_equal_file EXPECTED OUTPUT
+
test_done
diff --git a/test/T310-emacs.sh b/test/T310-emacs.sh
index 1b6660f0..a05b828a 100755
--- a/test/T310-emacs.sh
+++ b/test/T310-emacs.sh
@@ -485,6 +485,31 @@ Sender <sender@example.com> writes:
EOF
test_expect_equal_file EXPECTED OUTPUT
+test_begin_subtest "Reply with show.extra_headers set"
+notmuch config set show.extra_headers Received
+add_message '[from]="Sender <sender@example.com>"' \
+ [to]=test_suite_other@notmuchmail.org
+
+test_emacs "(let ((message-hidden-headers '()))
+ (notmuch-search \"id:\\\"${gen_msg_id}\\\"\")
+ (notmuch-test-wait)
+ (notmuch-search-reply-to-thread)
+ (test-output))"
+cat <<EOF >EXPECTED
+From: Notmuch Test Suite <test_suite_other@notmuchmail.org>
+To: Sender <sender@example.com>
+Subject: Re: ${test_subtest_name}
+In-Reply-To: <${gen_msg_id}>
+Fcc: ${MAIL_DIR}/sent
+References: <${gen_msg_id}>
+--text follows this line--
+Sender <sender@example.com> writes:
+
+> This is just a test message (#${gen_msg_cnt})
+EOF
+notmuch config set show.extra_headers
+test_expect_equal_file EXPECTED OUTPUT
+
test_begin_subtest "Reply from address in named group list within emacs"
add_message '[from]="Sender <sender@example.com>"' \
'[to]=group:test_suite@notmuchmail.org,someone@example.com\;' \
@@ -680,7 +705,7 @@ References: <XXX>
--text follows this line--
test_suite@notmuchmail.org writes:
-> This is just a test message (#7)
+> This is just a test message (#${gen_msg_cnt})
EOF
test_expect_equal_file EXPECTED OUTPUT
diff --git a/test/T350-crypto.sh b/test/T350-crypto.sh
index 8dbf8935..3c6626b4 100755
--- a/test/T350-crypto.sh
+++ b/test/T350-crypto.sh
@@ -13,16 +13,29 @@ test_description='PGP/MIME signature verification and decryption'
test_require_emacs
add_gnupg_home
-test_begin_subtest "emacs delivery of signed message"
+test_begin_subtest "emacs delivery of signed message via fcc"
test_expect_success \
'emacs_fcc_message \
"test signed message 001" \
"This is a test signed message." \
"(mml-secure-message-sign)"'
+test_begin_subtest "emacs delivery of signed message via fcc and smtp"
+emacs_deliver_message \
+ 'signed message sent via SMTP' \
+ 'This is a test that messages are sent via SMTP' \
+ "(add-hook 'message-send-mail-hook (lambda () (sleep-for 1)))
+ (mml-secure-message-sign)"
+msg_file=$(notmuch search --output=files subject:signed-message-sent-via-SMTP)
+test_expect_equal_message_body sent_message "$msg_file"
+
test_begin_subtest "signed part content-type indexing"
-output=$(notmuch search mimetype:multipart/signed and mimetype:application/pgp-signature | notmuch_search_sanitize)
-test_expect_equal "$output" "thread:XXX 2000-01-01 [1/1] Notmuch Test Suite; test signed message 001 (inbox signed)"
+notmuch search mimetype:multipart/signed and mimetype:application/pgp-signature | notmuch_search_sanitize > OUTPUT
+cat <<EOF >EXPECTED
+thread:XXX 2000-01-01 [1/1] Notmuch Test Suite; test signed message 001 (inbox signed)
+thread:XXX 2000-01-01 [1/1] Notmuch Test Suite; signed message sent via SMTP (inbox signed)
+EOF
+test_expect_equal_file EXPECTED OUTPUT
test_begin_subtest "signature verification"
output=$(notmuch show --format=json --verify subject:"test signed message 001" \
diff --git a/test/T370-search-folder-coherence.sh b/test/T370-search-folder-coherence.sh
index 0a2727e7..cf202bb3 100755
--- a/test/T370-search-folder-coherence.sh
+++ b/test/T370-search-folder-coherence.sh
@@ -24,8 +24,8 @@ test_expect_equal "$output" "No new mail."
test_begin_subtest "Multiple files for same message"
cat <<EOF >EXPECTED
-MAIL_DIR/msg-001
-MAIL_DIR/spam/msg-001
+MAIL_DIR/msg-XXX
+MAIL_DIR/spam/msg-XXX
EOF
notmuch search --output=files id:$id_x | notmuch_search_files_sanitize >OUTPUT
test_expect_equal_file EXPECTED OUTPUT
diff --git a/test/T392-python-cffi-notmuch.sh b/test/T392-python-cffi-notmuch.sh
new file mode 100755
index 00000000..15c8fc6b
--- /dev/null
+++ b/test/T392-python-cffi-notmuch.sh
@@ -0,0 +1,48 @@
+#!/usr/bin/env bash
+test_description="python bindings (notmuch test suite)"
+. $(dirname "$0")/test-lib.sh || exit 1
+
+if [ $NOTMUCH_HAVE_PYTHON3_CFFI -eq 0 -o $NOTMUCH_HAVE_PYTHON3_PYTEST -eq 0 ]; then
+ test_done
+fi
+
+add_email_corpus
+
+cat <<EOF > recurse.py
+from notmuch2 import Database
+def show_msgs(msgs, level):
+ print('{:s} {:s}'.format(' ' * level*4, type(msgs).__name__))
+ for msg in msgs:
+ print('{:s} {:s}'.format(' ' * (level*4+2), type(msg).__name__))
+ replies=msg.replies()
+ show_msgs(replies, level+1)
+db = Database(config=Database.CONFIG.SEARCH)
+msg=db.find("87ocn0qh6d.fsf@yoom.home.cworth.org")
+threads = db.threads(query="thread:"+msg.threadid)
+thread = next (threads)
+show_msgs(thread, 0)
+EOF
+
+test_begin_subtest "recursive traversal of replies (no crash)"
+test_python < recurse.py
+error=$?
+test_expect_equal "${error}" 0
+
+test_begin_subtest "recursive traversal of replies (output)"
+test_python < recurse.py
+tail -n 10 < OUTPUT > OUTPUT.sample
+cat <<EOF > EXPECTED
+ OwnedMessage
+ MessageIter
+ OwnedMessage
+ MessageIter
+ OwnedMessage
+ MessageIter
+ OwnedMessage
+ MessageIter
+ OwnedMessage
+ MessageIter
+EOF
+test_expect_equal_file EXPECTED OUTPUT.sample
+
+test_done
diff --git a/test/T440-emacs-hello.sh b/test/T440-emacs-hello.sh
index a1ed1c2b..842781a4 100755
--- a/test/T440-emacs-hello.sh
+++ b/test/T440-emacs-hello.sh
@@ -68,6 +68,16 @@ test_emacs '(notmuch-hello)
notmuch tag -$tag '*'
test_expect_equal_file $EXPECTED/notmuch-hello-long-names OUTPUT
+test_begin_subtest "All tags show up"
+tag=exclude_me
+notmuch tag +$tag '*'
+notmuch config set search.exclude_tags $tag
+test_emacs '(notmuch-hello)
+ (test-output)'
+notmuch tag -$tag '*'
+test_expect_equal_file $EXPECTED/notmuch-hello-all-tags OUTPUT
+
+test_done
test_begin_subtest "notmuch-hello with nonexistent CWD"
test_emacs '
(notmuch-hello)
diff --git a/test/T450-emacs-show.sh b/test/T450-emacs-show.sh
index 4b5f5fde..057ad37e 100755
--- a/test/T450-emacs-show.sh
+++ b/test/T450-emacs-show.sh
@@ -220,7 +220,9 @@ test_emacs '(notmuch-show "id:basic-encrypted@crypto.notmuchmail.org")
test_expect_equal_file $EXPECTED/notmuch-show-decrypted-message OUTPUT
test_begin_subtest "show encrypted rfc822 message"
-test_subtest_known_broken
+if ${TEST_EMACS} --quick --batch --eval '(kill-emacs (if (version< emacs-version "28") 0 1))'; then
+ test_subtest_known_broken
+fi
test_emacs '(notmuch-show "id:encrypted-rfc822-attachment@crypto.notmuchmail.org")
(test-visible-output)'
test_expect_code 1 'fgrep "!!!" OUTPUT'
diff --git a/test/T562-lib-database.sh b/test/T562-lib-database.sh
index 769fe86e..2314efd2 100755
--- a/test/T562-lib-database.sh
+++ b/test/T562-lib-database.sh
@@ -9,10 +9,8 @@ test_begin_subtest "building database"
test_expect_success "NOTMUCH_NEW"
cat <<EOF > c_head
-#include <stdio.h>
-#include <notmuch.h>
#include <notmuch-test.h>
-#include <talloc.h>
+
int main (int argc, char** argv)
{
notmuch_database_t *db;
@@ -82,7 +80,7 @@ cat <<EOF > EXPECTED
== stdout ==
0
== stderr ==
-A Xapian exception occurred at lib/database.cc:XXX: Database has been closed
+A Xapian exception occurred at database.cc:XXX: Database has been closed
EOF
test_expect_equal_file EXPECTED OUTPUT
@@ -147,7 +145,7 @@ cat <<EOF > EXPECTED
== stdout ==
1
== stderr ==
-A Xapian exception occurred at lib/database.cc:XXX: Database has been closed
+A Xapian exception occurred at database.cc:XXX: Database has been closed
EOF
test_expect_equal_file EXPECTED OUTPUT
diff --git a/test/T563-lib-directory.sh b/test/T563-lib-directory.sh
index 28325ff2..ebd7fcb2 100755
--- a/test/T563-lib-directory.sh
+++ b/test/T563-lib-directory.sh
@@ -9,10 +9,8 @@ test_begin_subtest "building database"
test_expect_success "NOTMUCH_NEW"
cat <<EOF > c_head
-#include <stdio.h>
-#include <notmuch.h>
#include <notmuch-test.h>
-#include <talloc.h>
+
int main (int argc, char** argv)
{
notmuch_database_t *db;
@@ -53,7 +51,7 @@ cat <<EOF > EXPECTED
== stdout ==
1
== stderr ==
-A Xapian exception occurred at lib/directory.cc:XXX: Database has been closed
+A Xapian exception occurred at directory.cc:XXX: Database has been closed
EOF
test_expect_equal_file EXPECTED OUTPUT
@@ -70,7 +68,7 @@ cat <<EOF > EXPECTED
== stdout ==
1
== stderr ==
-A Xapian exception occurred at lib/directory.cc:XXX: Database has been closed
+A Xapian exception occurred at directory.cc:XXX: Database has been closed
EOF
test_expect_equal_file EXPECTED OUTPUT
diff --git a/test/T564-lib-query.sh b/test/T564-lib-query.sh
index 50b0a88e..ff1d4984 100755
--- a/test/T564-lib-query.sh
+++ b/test/T564-lib-query.sh
@@ -9,10 +9,8 @@ test_begin_subtest "building database"
test_expect_success "NOTMUCH_NEW"
cat <<EOF > c_head
-#include <stdio.h>
-#include <notmuch.h>
#include <notmuch-test.h>
-#include <talloc.h>
+
int main (int argc, char** argv)
{
notmuch_database_t *db;
diff --git a/test/T566-lib-message.sh b/test/T566-lib-message.sh
index ee55ef29..8b61d182 100755
--- a/test/T566-lib-message.sh
+++ b/test/T566-lib-message.sh
@@ -19,9 +19,8 @@ cat <<'EOF' > c_tail
EOF
cat <<EOF > c_head0
-#include <stdio.h>
-#include <notmuch.h>
#include <notmuch-test.h>
+
int main (int argc, char** argv)
{
notmuch_database_t *db;
diff --git a/test/T568-lib-thread.sh b/test/T568-lib-thread.sh
index 088e66dd..b45836cd 100755
--- a/test/T568-lib-thread.sh
+++ b/test/T568-lib-thread.sh
@@ -24,9 +24,8 @@ cat <<'EOF' > c_tail
EOF
cat <<EOF > c_head
-#include <stdio.h>
-#include <notmuch.h>
#include <notmuch-test.h>
+
int main (int argc, char** argv)
{
notmuch_database_t *db;
diff --git a/test/T590-libconfig.sh b/test/T590-libconfig.sh
index 9fa51fc0..26a1f033 100755
--- a/test/T590-libconfig.sh
+++ b/test/T590-libconfig.sh
@@ -23,8 +23,6 @@ EOF
}
cat <<EOF > c_head
-#include <string.h>
-#include <stdlib.h>
#include <notmuch-test.h>
int main (int argc, char** argv)
@@ -272,6 +270,29 @@ EOF
test_expect_equal_file EXPECTED OUTPUT
restore_database
+test_begin_subtest "notmuch_config_get_values (ignore leading/trailing whitespace)"
+cat c_head - c_tail <<'EOF' | test_C ${MAIL_DIR} ${NOTMUCH_CONFIG} %NULL%
+{
+ notmuch_config_values_t *values;
+ EXPECT0(notmuch_config_set (db, NOTMUCH_CONFIG_NEW_TAGS, " a ; b c ; d "));
+ for (values = notmuch_config_get_values (db, NOTMUCH_CONFIG_NEW_TAGS);
+ notmuch_config_values_valid (values);
+ notmuch_config_values_move_to_next (values))
+ {
+ puts (notmuch_config_values_get (values));
+ }
+}
+EOF
+cat <<'EOF' >EXPECTED
+== stdout ==
+a
+b c
+d
+== stderr ==
+EOF
+test_expect_equal_file EXPECTED OUTPUT
+restore_database
+
test_begin_subtest "notmuch_config_get_values_string"
cat c_head - c_tail <<'EOF' | test_C ${MAIL_DIR} ${NOTMUCH_CONFIG} %NULL%
{
@@ -418,6 +439,7 @@ cat <<'EOF' >EXPECTED
09: 'NULL'
10: 'USER_FULL_NAME'
11: '8000'
+12: 'NULL'
== stderr ==
EOF
unset MAILDIR
@@ -616,8 +638,6 @@ cp notmuch-config.bak notmuch-config
test_expect_equal_file EXPECTED OUTPUT
cat <<EOF > c_head2
-#include <string.h>
-#include <stdlib.h>
#include <notmuch-test.h>
int main (int argc, char** argv)
@@ -730,6 +750,7 @@ cat <<'EOF' >EXPECTED
09: 'test_suite_other@notmuchmail.org;test_suite@otherdomain.org'
10: 'Notmuch Test Suite'
11: '8000'
+12: 'NULL'
== stderr ==
EOF
test_expect_equal_file EXPECTED OUTPUT
@@ -763,6 +784,7 @@ cat <<'EOF' >EXPECTED
09: 'NULL'
10: 'USER_FULL_NAME'
11: '8000'
+12: 'NULL'
== stderr ==
EOF
test_expect_equal_file EXPECTED OUTPUT.clean
@@ -839,6 +861,7 @@ maildir.synchronize_flags true
new.ignore sekrit_junk
new.tags unread;inbox
search.exclude_tags foo;bar;fub
+show.extra_headers (null)
test.key1 testvalue1
test.key2 testvalue2
user.name Notmuch Test Suite
@@ -953,6 +976,7 @@ EOF
test_expect_equal_file EXPECTED OUTPUT
test_begin_subtest "open: database parameter overrides implicit config"
+cp $NOTMUCH_CONFIG ${NOTMUCH_CONFIG}.bak
notmuch config set database.path ${MAIL_DIR}/nonexistent
cat c_head3 - c_tail3 <<'EOF' | test_C ${MAIL_DIR}
const char *path = NULL;
@@ -963,6 +987,7 @@ cat c_head3 - c_tail3 <<'EOF' | test_C ${MAIL_DIR}
path = notmuch_database_get_path (db);
printf ("path: %s\n", path ? path : "(null)");
EOF
+cp ${NOTMUCH_CONFIG}.bak ${NOTMUCH_CONFIG}
cat <<EOF> EXPECTED
== stdout ==
status: 0
@@ -973,4 +998,43 @@ EOF
notmuch_dir_sanitize < OUTPUT > OUTPUT.clean
test_expect_equal_file EXPECTED OUTPUT.clean
+cat <<EOF > c_body
+ notmuch_status_t st = notmuch_database_open_with_config(NULL,
+ NOTMUCH_DATABASE_MODE_READ_ONLY,
+ "", NULL, &db, NULL);
+ printf ("status == SUCCESS: %d\n", st == NOTMUCH_STATUS_SUCCESS);
+ if (db) {
+ const char *mail_root = NULL;
+ mail_root = notmuch_config_get (db, NOTMUCH_CONFIG_MAIL_ROOT);
+ printf ("mail_root: %s\n", mail_root ? mail_root : "(null)");
+ }
+EOF
+
+cat <<EOF> EXPECTED.common
+== stdout ==
+status == SUCCESS: 0
+db == NULL: 1
+== stderr ==
+EOF
+
+test_begin_subtest "open/error: config=empty with no mail root in db "
+old_NOTMUCH_CONFIG=${NOTMUCH_CONFIG}
+unset NOTMUCH_CONFIG
+cat c_head3 c_body c_tail3 | test_C
+export NOTMUCH_CONFIG=${old_NOTMUCH_CONFIG}
+notmuch_dir_sanitize < OUTPUT > OUTPUT.clean
+test_expect_equal_file EXPECTED.common OUTPUT.clean
+
+test_begin_subtest "open/error: config=empty with no mail root in db (xdg)"
+old_NOTMUCH_CONFIG=${NOTMUCH_CONFIG}
+unset NOTMUCH_CONFIG
+backup_database
+mkdir -p home/.local/share/notmuch
+mv mail/.notmuch home/.local/share/notmuch/default
+cat c_head3 c_body c_tail3 | test_C
+restore_database
+export NOTMUCH_CONFIG=${old_NOTMUCH_CONFIG}
+notmuch_dir_sanitize < OUTPUT > OUTPUT.clean
+test_expect_equal_file EXPECTED.common OUTPUT.clean
+
test_done
diff --git a/test/T595-reopen.sh b/test/T595-reopen.sh
index 7375e2ac..1a517423 100755
--- a/test/T595-reopen.sh
+++ b/test/T595-reopen.sh
@@ -6,8 +6,6 @@ test_description="library reopen API"
add_email_corpus
cat <<EOF > c_head
-#include <string.h>
-#include <stdlib.h>
#include <notmuch-test.h>
int main (int argc, char** argv)
diff --git a/test/T610-message-property.sh b/test/T610-message-property.sh
index d0e52f4a..4ec85474 100755
--- a/test/T610-message-property.sh
+++ b/test/T610-message-property.sh
@@ -6,10 +6,6 @@ test_description="message property API"
add_email_corpus
cat <<EOF > c_head
-#include <stdio.h>
-#include <string.h>
-#include <stdlib.h>
-#include <talloc.h>
#include <notmuch-test.h>
void print_properties (notmuch_message_t *message, const char *prefix, notmuch_bool_t exact) {
diff --git a/test/T620-lock.sh b/test/T620-lock.sh
index 7aaaff2a..8f4c380f 100755
--- a/test/T620-lock.sh
+++ b/test/T620-lock.sh
@@ -9,9 +9,6 @@ if [ $NOTMUCH_HAVE_XAPIAN_DB_RETRY_LOCK -ne 1 ]; then
test_subtest_known_broken
fi
test_C ${MAIL_DIR} <<'EOF'
-#include <unistd.h>
-#include <stdlib.h>
-#include <sys/wait.h>
#include <notmuch-test.h>
void
diff --git a/test/T640-database-modified.sh b/test/T640-database-modified.sh
index 274105c7..636b20c7 100755
--- a/test/T640-database-modified.sh
+++ b/test/T640-database-modified.sh
@@ -10,11 +10,8 @@ test_begin_subtest "catching DatabaseModifiedError in _notmuch_message_ensure_me
first_id=$(notmuch search --output=messages '*'| head -1 | sed s/^id://)
test_C ${MAIL_DIR} <<EOF
-#include <unistd.h>
-#include <stdlib.h>
#include <notmuch-test.h>
-#include <talloc.h>
-#include <assert.h>
+
int
main (int argc, char **argv)
{
diff --git a/test/T750-gzip.sh b/test/T750-gzip.sh
index 4408d085..5648896f 100755
--- a/test/T750-gzip.sh
+++ b/test/T750-gzip.sh
@@ -58,13 +58,13 @@ test_expect_equal_file EXPECTED OUTPUT
test_begin_subtest "notmuch search --output=files with partially gzipped mail store"
notmuch search --output=files '*' | notmuch_search_files_sanitize > OUTPUT
cat <<EOF > EXPECTED
-MAIL_DIR/msg-001.gz
-MAIL_DIR/msg-002.gz
-MAIL_DIR/msg-003.gz
-MAIL_DIR/msg-004
-MAIL_DIR/msg-005.gz
-MAIL_DIR/msg-006
-MAIL_DIR/msg-007.gz
+MAIL_DIR/msg-XXX.gz
+MAIL_DIR/msg-XXX.gz
+MAIL_DIR/msg-XXX.gz
+MAIL_DIR/msg-XXX
+MAIL_DIR/msg-XXX.gz
+MAIL_DIR/msg-XXX
+MAIL_DIR/msg-XXX.gz
EOF
test_expect_equal_file EXPECTED OUTPUT
diff --git a/test/T800-asan.sh b/test/T800-asan.sh
new file mode 100755
index 00000000..8607732e
--- /dev/null
+++ b/test/T800-asan.sh
@@ -0,0 +1,39 @@
+#!/usr/bin/env bash
+test_description='run code with ASAN enabled against the library'
+. $(dirname "$0")/test-lib.sh || exit 1
+
+if [ $NOTMUCH_HAVE_ASAN -ne 1 ]; then
+ printf "Skipping due to missing ASAN support\n"
+ test_done
+fi
+
+add_email_corpus
+
+TEST_CFLAGS="-fsanitize=address"
+
+test_begin_subtest "open and destroy"
+test_C ${MAIL_DIR} ${NOTMUCH_CONFIG} <<EOF
+#include <notmuch.h>
+#include <stdio.h>
+
+int main(int argc, char **argv) {
+ notmuch_database_t *db = NULL;
+
+ notmuch_status_t st = notmuch_database_open_with_config(argv[1],
+ NOTMUCH_DATABASE_MODE_READ_ONLY,
+ argv[2], NULL, &db, NULL);
+
+ printf("db != NULL: %d\n", db != NULL);
+ if (db != NULL)
+ notmuch_database_destroy(db);
+ return 0;
+}
+EOF
+cat <<EOF > EXPECTED
+== stdout ==
+db != NULL: 1
+== stderr ==
+EOF
+test_expect_equal_file EXPECTED OUTPUT
+
+test_done
diff --git a/test/emacs.expected-output/notmuch-hello-all-tags b/test/emacs.expected-output/notmuch-hello-all-tags
new file mode 100644
index 00000000..65e479fa
--- /dev/null
+++ b/test/emacs.expected-output/notmuch-hello-all-tags
@@ -0,0 +1,11 @@
+ Welcome to notmuch. You have 52 messages.
+
+Search: .
+
+All tags: [hide]
+
+ 4 attachment 52 inbox 52 unread
+ 52 exclude_me 7 signed
+
+ Hit `?' for context-sensitive help in any Notmuch screen.
+ Customize Notmuch or this page.
diff --git a/test/notmuch-test.h b/test/notmuch-test.h
index 34dbb8e0..ed713099 100644
--- a/test/notmuch-test.h
+++ b/test/notmuch-test.h
@@ -1,7 +1,21 @@
#ifndef _NOTMUCH_TEST_H
#define _NOTMUCH_TEST_H
+#ifndef _GNU_SOURCE
+#define _GNU_SOURCE
+#endif
+
+#include <assert.h>
+#include <dlfcn.h>
+#include <fcntl.h>
#include <stdio.h>
#include <stdlib.h>
+#include <string.h>
+#include <sys/stat.h>
+#include <sys/types.h>
+#include <sys/wait.h>
+#include <talloc.h>
+#include <unistd.h>
+
#include <notmuch.h>
inline static void
@@ -14,4 +28,23 @@ expect0 (int line, notmuch_status_t ret)
}
#define EXPECT0(v) expect0 (__LINE__, v);
+
+inline static void *
+dlsym_next (const char *symbol)
+{
+ void *sym = dlsym (RTLD_NEXT, symbol);
+ char *str = dlerror ();
+
+ if (str != NULL) {
+ fprintf (stderr, "finding symbol '%s' failed: %s", symbol, str);
+ exit (77);
+ }
+ return sym;
+}
+
+#define WRAP_DLFUNC(_rtype, _func, _args) \
+ _rtype _func _args; \
+ _rtype _func _args { \
+ static _rtype (*_func##_orig) _args = NULL; \
+ if (! _func##_orig ) *(void **) (&_func##_orig) = dlsym_next (#_func);
#endif
diff --git a/test/setup.expected-output/config-with-comments b/test/setup.expected-output/config-with-comments
index 56c628e5..d8397714 100644
--- a/test/setup.expected-output/config-with-comments
+++ b/test/setup.expected-output/config-with-comments
@@ -31,7 +31,7 @@ path=/path/to/maildir
[user]
name=Test Suite
primary_email=test.suite@example.com
-other_email=another.suite@example.com;
+other_email=another.suite@example.com
# Configuration for "notmuch new"
#
@@ -60,7 +60,7 @@ tags=foo;bar;
# query will override that exclusion.
#
[search]
-exclude_tags=baz;
+exclude_tags=baz
# Maildir compatibility configuration
#
diff --git a/test/symbol-test.cc b/test/symbol-test.cc
index 9d73a571..9e956ddf 100644
--- a/test/symbol-test.cc
+++ b/test/symbol-test.cc
@@ -12,8 +12,10 @@ main (int argc, char **argv)
if (argc != 3)
return 1;
- if (notmuch_database_open_verbose (argv[1], NOTMUCH_DATABASE_MODE_READ_ONLY,
- &notmuch, &message)) {
+ if (notmuch_database_open_with_config (argv[1], NOTMUCH_DATABASE_MODE_READ_ONLY,
+ "",
+ NULL,
+ &notmuch, &message)) {
if (message) {
fputs (message, stderr);
free (message);
diff --git a/test/test-lib-emacs.sh b/test/test-lib-emacs.sh
index dde32177..a298526d 100644
--- a/test/test-lib-emacs.sh
+++ b/test/test-lib-emacs.sh
@@ -54,8 +54,9 @@ emacs_deliver_message () {
(message-goto-body)
(insert \"${body}\")
$*
- (notmuch-mua-send-and-exit))"
-
+ (let ((mml-secure-smime-sign-with-sender t)
+ (mml-secure-openpgp-sign-with-sender t))
+ (notmuch-mua-send-and-exit)))"
# In case message was sent properly, client waits for confirmation
# before exiting and resuming control here; therefore making sure
# that server exits by sending (KILL) signal to it is safe.
diff --git a/test/test-lib.sh b/test/test-lib.sh
index e476a69b..833bf5fe 100644
--- a/test/test-lib.sh
+++ b/test/test-lib.sh
@@ -145,7 +145,7 @@ add_gpgsm_home () {
mkdir -p -m 0700 "$GNUPGHOME"
gpgsm --batch --no-tty --no-common-certs-import --pinentry-mode=loopback --passphrase-fd 3 \
--disable-dirmngr --import >"$GNUPGHOME"/import.log 2>&1 3<<<'' <$NOTMUCH_SRCDIR/test/smime/0xE0972A47.p12
- fpr=$(gpgsm --batch --list-key test_suite@notmuchmail.org | sed -n 's/.*fingerprint: //p')
+ fpr=$(gpgsm --batch --with-colons --list-key test_suite@notmuchmail.org | awk -F: '/^fpr/ {print $10}')
echo "$fpr S relax" >> "$GNUPGHOME/trustlist.txt"
gpgsm --quiet --batch --no-tty --no-common-certs-import --disable-dirmngr --import < $NOTMUCH_SRCDIR/test/smime/ca.crt
echo "4D:E0:FF:63:C0:E9:EC:01:29:11:C8:7A:EE:DA:3A:9A:7F:6E:C1:0D S" >> "$GNUPGHOME/trustlist.txt"
@@ -432,6 +432,20 @@ test_expect_equal_file () {
test_diff_file_ "$1" "$2"
}
+# Like test_expect_equal_file, but compare the part of the two files after the first blank line
+test_expect_equal_message_body () {
+ exec 1>&6 2>&7 # Restore stdout and stderr
+ if [ -z "$inside_subtest" ]; then
+ error "bug in the test script: test_expect_equal_file without test_begin_subtest"
+ fi
+ test "$#" = 2 ||
+ error "bug in the test script: not 2 parameters to test_expect_equal_file"
+
+ expected=$(sed '1,/^$/d' "$1")
+ output=$(sed '1,/^$/d' "$2")
+ test_expect_equal "$expected" "$output"
+}
+
# Like test_expect_equal, but takes two filenames. Fails if either is empty
test_expect_equal_file_nonempty () {
exec 1>&6 2>&7 # Restore stdout and stderr
@@ -529,7 +543,7 @@ notmuch_debug_sanitize () {
}
notmuch_exception_sanitize () {
- perl -pe 's/(A Xapian exception occurred at .*[.]cc?):([0-9]*)/\1:XXX/'
+ perl -pe 's,(A Xapian exception occurred at) .*?([^/]*[.]cc?):([0-9]*),\1 \2:XXX,'
}
notmuch_search_sanitize () {
@@ -537,7 +551,7 @@ notmuch_search_sanitize () {
}
notmuch_search_files_sanitize () {
- notmuch_dir_sanitize
+ notmuch_dir_sanitize | sed 's/msg-[0-9][0-9][0-9]/msg-XXX/'
}
notmuch_dir_sanitize () {