From 32af882648325ba1a24f031c0d2728b2553a5e6e Mon Sep 17 00:00:00 2001 From: Anton Khirnov Date: Mon, 28 Jul 2025 09:37:58 +0200 Subject: [PATCH] test: add a known broken test for DatabaseModifiedError from threads iteration This is similar to previously added T641, except here we iterate over threads rather than messages. After f375ea1add121c428f261473512831a169dfe335, the DatabaseModifiedError raised by Xapian is now handled in _notmuch_message_create(), resulting in a NULL message being returned to _notmuch_thread_create(), which currently triggers an internal error. --- test/T642-database-modified-threads.sh | 102 +++++++++++++++++++++++++ 1 file changed, 102 insertions(+) create mode 100755 test/T642-database-modified-threads.sh diff --git a/test/T642-database-modified-threads.sh b/test/T642-database-modified-threads.sh new file mode 100755 index 00000000..00bd7808 --- /dev/null +++ b/test/T642-database-modified-threads.sh @@ -0,0 +1,102 @@ +#!/usr/bin/env bash +test_description="handling NOTMUCH_STATUS_OPERATION_INVALIDATED in _notmuch_thread_create" +. $(dirname "$0")/test-lib.sh || exit 1 + +# See comment at the top of T641-database-modified-messages.sh +# for more details. + +# add default corpus for the initial query +add_email_corpus +# As per above, copy LKML corpus email files, but do not add them to the DB yet. +cp -a $NOTMUCH_SRCDIR/test/corpora/lkml ${MAIL_DIR}/ + +test_begin_subtest "handling NOTMUCH_STATUS_OPERATION_INVALIDATED in _notmuch_thread_create" +test_subtest_known_broken + +test_C ${MAIL_DIR} < + +int +main (int argc, char **argv) +{ + const char *path = argv[1]; + + notmuch_database_t *rw_db, *ro_db; + notmuch_messages_t *messages; + notmuch_threads_t *threads; + notmuch_query_t *query_ro, *query_rw; + notmuch_status_t status; + char* msg = NULL; + unsigned try; + + EXPECT0 (notmuch_database_open_with_config (argv[1], + NOTMUCH_DATABASE_MODE_READ_ONLY, + "", NULL, &ro_db, &msg)); + if (msg) fputs (msg, stderr); + assert (ro_db); + + query_ro = notmuch_query_create (ro_db, ""); + assert (query_ro); + + EXPECT0 (notmuch_query_search_threads (query_ro, &threads)); + + // index the previously copied LKML corpus files + EXPECT0 (system ("notmuch new --quiet")); + + EXPECT0 (notmuch_database_open_with_config (argv[1], + NOTMUCH_DATABASE_MODE_READ_WRITE, + "", NULL, &rw_db, &msg)); + if (msg) fputs (msg, stderr); + + query_rw = notmuch_query_create (rw_db, ""); + EXPECT0 (notmuch_query_search_messages (query_rw, &messages)); + + for (; + ! notmuch_messages_status (messages); + notmuch_messages_move_to_next (messages)) { + notmuch_message_t *message = notmuch_messages_get (messages); + EXPECT0 (notmuch_message_add_tag (message, "tag")); + } + + notmuch_database_close (rw_db); + + // try iterating over the query up to twice, we expect a Xapian + // DatabaseModifiedError (mapped to NOTMUCH_STATUS_OPERATION_INVALIDATED) + // on the first try + for (try = 0; try < 2; try++) { + for (; + notmuch_threads_valid (threads); + notmuch_threads_move_to_next (threads)) { + notmuch_thread_t *thread = notmuch_threads_get (threads); + } + status = NOTMUCH_STATUS_ITERATOR_EXHAUSTED; + if (status != NOTMUCH_STATUS_OPERATION_INVALIDATED) + break; + + notmuch_query_destroy (query_ro); + notmuch_database_close (ro_db); + + EXPECT0 (notmuch_database_open_with_config (argv[1], + NOTMUCH_DATABASE_MODE_READ_ONLY, + "", NULL, &ro_db, &msg)); + query_ro = notmuch_query_create (ro_db, ""); + assert (query_ro); + EXPECT0 (notmuch_query_search_threads (query_ro, &threads)); + } + + if (status == NOTMUCH_STATUS_ITERATOR_EXHAUSTED) + printf ("SUCCESS\n"); + else + printf ("status: %s\n", notmuch_status_to_string (status)); + return 0; +} +EOF + +cat <<'EOF' >EXPECTED +== stdout == +SUCCESS +== stderr == +EOF +test_expect_equal_file EXPECTED OUTPUT + +test_done -- 2.45.2