unofficial mirror of notmuch@notmuchmail.org
 help / color / mirror / code / Atom feed
* final(?) batch of api cleanup for exception handling
@ 2020-07-26 11:59 David Bremner
  2020-07-26 11:59 ` [PATCH 01/13] test: add regression test for n_messages_collect_tags David Bremner
                   ` (12 more replies)
  0 siblings, 13 replies; 17+ messages in thread
From: David Bremner @ 2020-07-26 11:59 UTC (permalink / raw)
  To: notmuch

Hopefully this covers completely the current API for error handling on
closed databases. For the most part, it's not that I care about
supporting operations on closed databases, but rather it provides a
good opportunity to make sure exceptions are being caught at the the
boundary of libnotmuch.

The not-completely-trivial changes are

[PATCH 05/13] lib: catch exceptions in  n_directory_get_child_directories
[PATCH 07/13] lib: catch exceptions in n_directory_get_child_files
[PATCH 13/13] lib: return NULL from n_d_get_default_indexopts on

The last one is a repost to keep the series together. 

^ permalink raw reply	[flat|nested] 17+ messages in thread

* [PATCH 01/13] test: add regression test for n_messages_collect_tags
  2020-07-26 11:59 final(?) batch of api cleanup for exception handling David Bremner
@ 2020-07-26 11:59 ` David Bremner
  2020-07-26 11:59 ` [PATCH 02/13] test: split header for lib-message tests David Bremner
                   ` (11 subsequent siblings)
  12 siblings, 0 replies; 17+ messages in thread
From: David Bremner @ 2020-07-26 11:59 UTC (permalink / raw)
  To: notmuch; +Cc: David Bremner

Also test n_messages_destroy.
---
 test/T568-lib-thread.sh | 31 +++++++++++++++++++++++++++++++
 1 file changed, 31 insertions(+)

diff --git a/test/T568-lib-thread.sh b/test/T568-lib-thread.sh
index 66066854..ac13d986 100755
--- a/test/T568-lib-thread.sh
+++ b/test/T568-lib-thread.sh
@@ -285,6 +285,37 @@ unread
 EOF
 test_expect_equal_file EXPECTED OUTPUT
 
+test_begin_subtest "collect tags with closed database"
+cat c_head - c_tail <<'EOF' | test_C ${MAIL_DIR}
+    {
+      notmuch_messages_t *messages = notmuch_thread_get_messages (thread);
+
+      notmuch_tags_t *tags = notmuch_messages_collect_tags (messages);
+
+      const char *tag;
+      for (tags = notmuch_thread_get_tags (thread);
+           notmuch_tags_valid (tags);
+           notmuch_tags_move_to_next (tags))
+        {
+          tag = notmuch_tags_get (tags);
+          printf ("%s\n", tag);
+        }
+      notmuch_tags_destroy (tags);
+      notmuch_messages_destroy (messages);
+
+      printf("SUCCESS\n");
+    }
+EOF
+cat <<EOF > EXPECTED
+== stdout ==
+inbox
+signed
+unread
+SUCCESS
+== stderr ==
+EOF
+test_expect_equal_file EXPECTED OUTPUT
+
 test_begin_subtest "destroy thread with closed database"
 cat c_head - c_tail <<'EOF' | test_C ${MAIL_DIR}
     {
-- 
2.27.0

^ permalink raw reply related	[flat|nested] 17+ messages in thread

* [PATCH 02/13] test: split header for lib-message tests.
  2020-07-26 11:59 final(?) batch of api cleanup for exception handling David Bremner
  2020-07-26 11:59 ` [PATCH 01/13] test: add regression test for n_messages_collect_tags David Bremner
@ 2020-07-26 11:59 ` David Bremner
  2020-07-26 11:59 ` [PATCH 03/13] test: regression test for n_m_get_filenames David Bremner
                   ` (10 subsequent siblings)
  12 siblings, 0 replies; 17+ messages in thread
From: David Bremner @ 2020-07-26 11:59 UTC (permalink / raw)
  To: notmuch; +Cc: David Bremner

This allows finer control over when to close the database.
---
 test/T566-lib-message.sh | 6 ++++--
 1 file changed, 4 insertions(+), 2 deletions(-)

diff --git a/test/T566-lib-message.sh b/test/T566-lib-message.sh
index 4c9fc0df..7e8f8959 100755
--- a/test/T566-lib-message.sh
+++ b/test/T566-lib-message.sh
@@ -18,7 +18,7 @@ cat <<'EOF' > c_tail
 }
 EOF
 
-cat <<EOF > c_head
+cat <<EOF > c_head0
 #include <stdio.h>
 #include <notmuch.h>
 #include <notmuch-test.h>
@@ -36,9 +36,11 @@ int main (int argc, char** argv)
      exit (1);
    }
    EXPECT0(notmuch_database_find_message (db, id, &message));
-   EXPECT0(notmuch_database_close (db));
 EOF
 
+cp c_head0 c_head
+echo "   EXPECT0(notmuch_database_close (db));" >> c_head
+
 test_begin_subtest "Handle getting message-id from closed database"
 cat c_head - c_tail <<'EOF' | test_C ${MAIL_DIR}
     {
-- 
2.27.0

^ permalink raw reply related	[flat|nested] 17+ messages in thread

* [PATCH 03/13] test: regression test for n_m_get_filenames
  2020-07-26 11:59 final(?) batch of api cleanup for exception handling David Bremner
  2020-07-26 11:59 ` [PATCH 01/13] test: add regression test for n_messages_collect_tags David Bremner
  2020-07-26 11:59 ` [PATCH 02/13] test: split header for lib-message tests David Bremner
@ 2020-07-26 11:59 ` David Bremner
  2020-07-26 11:59 ` [PATCH 04/13] test: add known broken test for n_directory_get_child_directories David Bremner
                   ` (9 subsequent siblings)
  12 siblings, 0 replies; 17+ messages in thread
From: David Bremner @ 2020-07-26 11:59 UTC (permalink / raw)
  To: notmuch; +Cc: David Bremner

Closing the database after the iterator is created is not a problem.
---
 test/T566-lib-message.sh | 23 +++++++++++++++++++++++
 1 file changed, 23 insertions(+)

diff --git a/test/T566-lib-message.sh b/test/T566-lib-message.sh
index 7e8f8959..d3765220 100755
--- a/test/T566-lib-message.sh
+++ b/test/T566-lib-message.sh
@@ -149,6 +149,29 @@ A Xapian exception occurred at lib/message.cc:XXX: Database has been closed
 EOF
 test_expect_equal_file EXPECTED OUTPUT
 
+test_begin_subtest "iterate over all message filenames from closed database"
+cat c_head0 - c_tail <<'EOF' | test_C ${MAIL_DIR}
+    {
+        notmuch_filenames_t *filenames;
+        filenames = notmuch_message_get_filenames (message);
+        EXPECT0(notmuch_database_close (db));
+        for (; notmuch_filenames_valid (filenames);
+               notmuch_filenames_move_to_next (filenames)) {
+            const char *filename = notmuch_filenames_get (filenames);
+            printf("%s\n", filename);
+        }
+        notmuch_filenames_destroy (filenames);
+        printf("SUCCESS\n");
+    }
+EOF
+cat <<EOF > EXPECTED
+== stdout ==
+MAIL_DIR/01:2,
+SUCCESS
+== stderr ==
+EOF
+test_expect_equal_file EXPECTED OUTPUT
+
 test_begin_subtest "Handle getting ghost flag from closed database"
 cat c_head - c_tail <<'EOF' | test_C ${MAIL_DIR}
     {
-- 
2.27.0

^ permalink raw reply related	[flat|nested] 17+ messages in thread

* [PATCH 04/13] test: add known broken test for n_directory_get_child_directories
  2020-07-26 11:59 final(?) batch of api cleanup for exception handling David Bremner
                   ` (2 preceding siblings ...)
  2020-07-26 11:59 ` [PATCH 03/13] test: regression test for n_m_get_filenames David Bremner
@ 2020-07-26 11:59 ` David Bremner
  2020-07-26 11:59 ` [PATCH 05/13] lib: catch exceptions in n_directory_get_child_directories David Bremner
                   ` (8 subsequent siblings)
  12 siblings, 0 replies; 17+ messages in thread
From: David Bremner @ 2020-07-26 11:59 UTC (permalink / raw)
  To: notmuch; +Cc: David Bremner

The error message here may need adjusting.
---
 test/T563-lib-directory.sh | 61 ++++++++++++++++++++++++++++++++++++++
 1 file changed, 61 insertions(+)
 create mode 100755 test/T563-lib-directory.sh

diff --git a/test/T563-lib-directory.sh b/test/T563-lib-directory.sh
new file mode 100755
index 00000000..e9e4cd0f
--- /dev/null
+++ b/test/T563-lib-directory.sh
@@ -0,0 +1,61 @@
+#!/usr/bin/env bash
+test_description="notmuch_database_* API"
+
+. $(dirname "$0")/test-lib.sh || exit 1
+
+add_email_corpus
+
+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;
+   notmuch_directory_t *dir;
+   notmuch_status_t stat = NOTMUCH_STATUS_SUCCESS;
+   char *msg = NULL;
+
+   stat = notmuch_database_open_verbose (argv[1], NOTMUCH_DATABASE_MODE_READ_WRITE, &db, &msg);
+   if (stat != NOTMUCH_STATUS_SUCCESS) {
+     fprintf (stderr, "error opening database: %d %s\n", stat, msg ? msg : "");
+     exit (1);
+   }
+
+   EXPECT0(notmuch_database_get_directory (db, "", &dir));
+   EXPECT0(notmuch_database_close (db));
+EOF
+
+cat <<'EOF' > c_tail
+   if (stat) {
+       const char *stat_str = notmuch_database_status_string (db);
+       if (stat_str)
+           fputs (stat_str, stderr);
+    }
+
+}
+EOF
+
+test_begin_subtest "get child directories for a closed db"
+test_subtest_known_broken
+cat c_head - c_tail <<'EOF' | test_C ${MAIL_DIR}
+    {
+        notmuch_filenames_t *children;
+        children = notmuch_directory_get_child_directories (dir);
+        printf ("%d\n", children == NULL);
+        stat = NOTMUCH_STATUS_XAPIAN_EXCEPTION;
+    }
+EOF
+cat <<EOF > EXPECTED
+== stdout ==
+1
+== stderr ==
+A Xapian exception occurred at lib/directory.cc:XXX: Database has been closed
+EOF
+test_expect_equal_file EXPECTED OUTPUT
+
+test_done
-- 
2.27.0

^ permalink raw reply related	[flat|nested] 17+ messages in thread

* [PATCH 05/13] lib: catch exceptions in n_directory_get_child_directories
  2020-07-26 11:59 final(?) batch of api cleanup for exception handling David Bremner
                   ` (3 preceding siblings ...)
  2020-07-26 11:59 ` [PATCH 04/13] test: add known broken test for n_directory_get_child_directories David Bremner
@ 2020-07-26 11:59 ` David Bremner
  2020-07-26 11:59 ` [PATCH 06/13] test: add known broken test for n_directory_get_child_files David Bremner
                   ` (7 subsequent siblings)
  12 siblings, 0 replies; 17+ messages in thread
From: David Bremner @ 2020-07-26 11:59 UTC (permalink / raw)
  To: notmuch; +Cc: David Bremner

Also clarify API in error case.
---
 lib/directory.cc           | 23 ++++++++++++++++++++---
 lib/notmuch.h              |  2 ++
 test/T563-lib-directory.sh |  1 -
 3 files changed, 22 insertions(+), 4 deletions(-)

diff --git a/lib/directory.cc b/lib/directory.cc
index 09b49245..eb59d24d 100644
--- a/lib/directory.cc
+++ b/lib/directory.cc
@@ -49,6 +49,19 @@ struct _notmuch_directory {
     time_t mtime;
 };
 
+#define LOG_XAPIAN_EXCEPTION(directory, error) _log_xapian_exception (__location__, directory, error)
+
+static void
+_log_xapian_exception (const char *where, notmuch_directory_t *dir,  const Xapian::Error error) {
+    notmuch_database_t *notmuch = dir->notmuch;
+    _notmuch_database_log (notmuch,
+			   "A Xapian exception occurred at %s: %s\n",
+			   where,
+			   error.get_msg ().c_str ());
+    notmuch->exception_reported = true;
+}
+
+
 /* We end up having to call the destructor explicitly because we had
  * to use "placement new" in order to initialize C++ objects within a
  * block that we allocated with talloc. So C++ is making talloc
@@ -270,14 +283,18 @@ notmuch_filenames_t *
 notmuch_directory_get_child_directories (notmuch_directory_t *directory)
 {
     char *term;
-    notmuch_filenames_t *child_directories;
+    notmuch_filenames_t *child_directories = NULL;
 
     term = talloc_asprintf (directory, "%s%u:",
 			    _find_prefix ("directory-direntry"),
 			    directory->document_id);
 
-    child_directories = _create_filenames_for_terms_with_prefix (directory,
-								 directory->notmuch, term);
+    try {
+	child_directories = _create_filenames_for_terms_with_prefix (directory,
+								     directory->notmuch, term);
+    } catch (Xapian::Error &error) {
+	LOG_XAPIAN_EXCEPTION (directory, error);
+    }
 
     talloc_free (term);
 
diff --git a/lib/notmuch.h b/lib/notmuch.h
index f9e9cc41..03db3b24 100644
--- a/lib/notmuch.h
+++ b/lib/notmuch.h
@@ -2158,6 +2158,8 @@ notmuch_directory_get_child_files (notmuch_directory_t *directory);
  *
  * The returned filenames will be the basename-entries only (not
  * complete paths).
+ *
+ * Returns NULL if it triggers a Xapian exception
  */
 notmuch_filenames_t *
 notmuch_directory_get_child_directories (notmuch_directory_t *directory);
diff --git a/test/T563-lib-directory.sh b/test/T563-lib-directory.sh
index e9e4cd0f..4d8b7e82 100755
--- a/test/T563-lib-directory.sh
+++ b/test/T563-lib-directory.sh
@@ -41,7 +41,6 @@ cat <<'EOF' > c_tail
 EOF
 
 test_begin_subtest "get child directories for a closed db"
-test_subtest_known_broken
 cat c_head - c_tail <<'EOF' | test_C ${MAIL_DIR}
     {
         notmuch_filenames_t *children;
-- 
2.27.0

^ permalink raw reply related	[flat|nested] 17+ messages in thread

* [PATCH 06/13] test: add known broken test for n_directory_get_child_files
  2020-07-26 11:59 final(?) batch of api cleanup for exception handling David Bremner
                   ` (4 preceding siblings ...)
  2020-07-26 11:59 ` [PATCH 05/13] lib: catch exceptions in n_directory_get_child_directories David Bremner
@ 2020-07-26 11:59 ` David Bremner
  2020-07-26 11:59 ` [PATCH 07/13] lib: catch exceptions in n_directory_get_child_files David Bremner
                   ` (6 subsequent siblings)
  12 siblings, 0 replies; 17+ messages in thread
From: David Bremner @ 2020-07-26 11:59 UTC (permalink / raw)
  To: notmuch; +Cc: David Bremner

This is a clone of the one for get_child_directories
---
 test/T563-lib-directory.sh | 18 ++++++++++++++++++
 1 file changed, 18 insertions(+)

diff --git a/test/T563-lib-directory.sh b/test/T563-lib-directory.sh
index 4d8b7e82..bbd12e12 100755
--- a/test/T563-lib-directory.sh
+++ b/test/T563-lib-directory.sh
@@ -57,4 +57,22 @@ A Xapian exception occurred at lib/directory.cc:XXX: Database has been closed
 EOF
 test_expect_equal_file EXPECTED OUTPUT
 
+test_begin_subtest "get child filenames for a closed db"
+test_subtest_known_broken
+cat c_head - c_tail <<'EOF' | test_C ${MAIL_DIR}
+    {
+        notmuch_filenames_t *children;
+        children = notmuch_directory_get_child_files (dir);
+        printf ("%d\n", children == NULL);
+        stat = NOTMUCH_STATUS_XAPIAN_EXCEPTION;
+    }
+EOF
+cat <<EOF > EXPECTED
+== stdout ==
+1
+== stderr ==
+A Xapian exception occurred at lib/directory.cc:XXX: Database has been closed
+EOF
+test_expect_equal_file EXPECTED OUTPUT
+
 test_done
-- 
2.27.0

^ permalink raw reply related	[flat|nested] 17+ messages in thread

* [PATCH 07/13] lib: catch exceptions in n_directory_get_child_files
  2020-07-26 11:59 final(?) batch of api cleanup for exception handling David Bremner
                   ` (5 preceding siblings ...)
  2020-07-26 11:59 ` [PATCH 06/13] test: add known broken test for n_directory_get_child_files David Bremner
@ 2020-07-26 11:59 ` David Bremner
  2020-07-26 11:59 ` [PATCH 08/13] test: regression test for n_directory_delete with closed db David Bremner
                   ` (5 subsequent siblings)
  12 siblings, 0 replies; 17+ messages in thread
From: David Bremner @ 2020-07-26 11:59 UTC (permalink / raw)
  To: notmuch; +Cc: David Bremner

Also clarify API in error case.
---
 lib/directory.cc           | 12 ++++++++----
 lib/notmuch.h              |  2 ++
 test/T563-lib-directory.sh |  1 -
 3 files changed, 10 insertions(+), 5 deletions(-)

diff --git a/lib/directory.cc b/lib/directory.cc
index eb59d24d..044cd680 100644
--- a/lib/directory.cc
+++ b/lib/directory.cc
@@ -264,15 +264,19 @@ notmuch_filenames_t *
 notmuch_directory_get_child_files (notmuch_directory_t *directory)
 {
     char *term;
-    notmuch_filenames_t *child_files;
+    notmuch_filenames_t *child_files = NULL;
 
     term = talloc_asprintf (directory, "%s%u:",
 			    _find_prefix ("file-direntry"),
 			    directory->document_id);
 
-    child_files = _create_filenames_for_terms_with_prefix (directory,
-							   directory->notmuch,
-							   term);
+    try {
+	child_files = _create_filenames_for_terms_with_prefix (directory,
+							       directory->notmuch,
+							       term);
+    } catch (Xapian::Error &error) {
+	LOG_XAPIAN_EXCEPTION (directory, error);
+    }
 
     talloc_free (term);
 
diff --git a/lib/notmuch.h b/lib/notmuch.h
index 03db3b24..d52fa976 100644
--- a/lib/notmuch.h
+++ b/lib/notmuch.h
@@ -2148,6 +2148,8 @@ notmuch_directory_get_mtime (notmuch_directory_t *directory);
  *
  * The returned filenames will be the basename-entries only (not
  * complete paths).
+ *
+ * Returns NULL if it triggers a Xapian exception
  */
 notmuch_filenames_t *
 notmuch_directory_get_child_files (notmuch_directory_t *directory);
diff --git a/test/T563-lib-directory.sh b/test/T563-lib-directory.sh
index bbd12e12..739469a6 100755
--- a/test/T563-lib-directory.sh
+++ b/test/T563-lib-directory.sh
@@ -58,7 +58,6 @@ EOF
 test_expect_equal_file EXPECTED OUTPUT
 
 test_begin_subtest "get child filenames for a closed db"
-test_subtest_known_broken
 cat c_head - c_tail <<'EOF' | test_C ${MAIL_DIR}
     {
         notmuch_filenames_t *children;
-- 
2.27.0

^ permalink raw reply related	[flat|nested] 17+ messages in thread

* [PATCH 08/13] test: regression test for n_directory_delete with closed db.
  2020-07-26 11:59 final(?) batch of api cleanup for exception handling David Bremner
                   ` (6 preceding siblings ...)
  2020-07-26 11:59 ` [PATCH 07/13] lib: catch exceptions in n_directory_get_child_files David Bremner
@ 2020-07-26 11:59 ` David Bremner
  2020-07-27  0:55   ` [PATCH 1/2] test: known broken " David Bremner
  2020-07-27 12:06   ` [PATCH 08/13] test: regression test for n_directory_delete with closed db David Bremner
  2020-07-26 11:59 ` [PATCH 09/13] test: regression test for n_directory_{get,set}_mtime David Bremner
                   ` (4 subsequent siblings)
  12 siblings, 2 replies; 17+ messages in thread
From: David Bremner @ 2020-07-26 11:59 UTC (permalink / raw)
  To: notmuch; +Cc: David Bremner

To the best of my current understanding, it's a bug in Xapian that no
exception is thrown here. The test should pass in either case.
---
 test/T563-lib-directory.sh | 19 ++++++++++++++++++-
 1 file changed, 18 insertions(+), 1 deletion(-)

diff --git a/test/T563-lib-directory.sh b/test/T563-lib-directory.sh
index 739469a6..4de31078 100755
--- a/test/T563-lib-directory.sh
+++ b/test/T563-lib-directory.sh
@@ -26,7 +26,7 @@ int main (int argc, char** argv)
      exit (1);
    }
 
-   EXPECT0(notmuch_database_get_directory (db, "", &dir));
+   EXPECT0(notmuch_database_get_directory (db, "bar", &dir));
    EXPECT0(notmuch_database_close (db));
 EOF
 
@@ -74,4 +74,21 @@ A Xapian exception occurred at lib/directory.cc:XXX: Database has been closed
 EOF
 test_expect_equal_file EXPECTED OUTPUT
 
+backup_database
+test_begin_subtest "delete directory document for a closed db"
+cat c_head - c_tail <<'EOF' | test_C ${MAIL_DIR}
+    {
+        stat = notmuch_directory_delete (dir);
+        printf ("%d\n", stat == NOTMUCH_STATUS_SUCCESS || stat == NOTMUCH_STATUS_XAPIAN_EXCEPTION);
+        stat = NOTMUCH_STATUS_SUCCESS;
+    }
+EOF
+cat <<EOF > EXPECTED
+== stdout ==
+1
+== stderr ==
+EOF
+test_expect_equal_file EXPECTED OUTPUT
+restore_database
+
 test_done
-- 
2.27.0

^ permalink raw reply related	[flat|nested] 17+ messages in thread

* [PATCH 09/13] test: regression test for n_directory_{get,set}_mtime
  2020-07-26 11:59 final(?) batch of api cleanup for exception handling David Bremner
                   ` (7 preceding siblings ...)
  2020-07-26 11:59 ` [PATCH 08/13] test: regression test for n_directory_delete with closed db David Bremner
@ 2020-07-26 11:59 ` David Bremner
  2020-07-26 11:59 ` [PATCH 10/13] test: regression test for n_d_get_config_list on closed db David Bremner
                   ` (3 subsequent siblings)
  12 siblings, 0 replies; 17+ messages in thread
From: David Bremner @ 2020-07-26 11:59 UTC (permalink / raw)
  To: notmuch; +Cc: David Bremner

The mtime is cached, so closing the db is not a problem. Writing the
mtime throws an exception, which is caught.
---
 test/T563-lib-directory.sh | 18 ++++++++++++++++++
 1 file changed, 18 insertions(+)

diff --git a/test/T563-lib-directory.sh b/test/T563-lib-directory.sh
index 4de31078..c45bc5f8 100755
--- a/test/T563-lib-directory.sh
+++ b/test/T563-lib-directory.sh
@@ -91,4 +91,22 @@ EOF
 test_expect_equal_file EXPECTED OUTPUT
 restore_database
 
+backup_database
+test_begin_subtest "get/set mtime of directory for a closed db"
+cat c_head - c_tail <<'EOF' | test_C ${MAIL_DIR}
+    {
+        time_t stamp = notmuch_directory_get_mtime (dir);
+        stat = notmuch_directory_set_mtime (dir, stamp);
+        printf ("%d\n", stat == NOTMUCH_STATUS_XAPIAN_EXCEPTION);
+    }
+EOF
+cat <<EOF > EXPECTED
+== stdout ==
+1
+== stderr ==
+A Xapian exception occurred setting directory mtime: Database has been closed.
+EOF
+test_expect_equal_file EXPECTED OUTPUT
+restore_database
+
 test_done
-- 
2.27.0

^ permalink raw reply related	[flat|nested] 17+ messages in thread

* [PATCH 10/13] test: regression test for n_d_get_config_list on closed db.
  2020-07-26 11:59 final(?) batch of api cleanup for exception handling David Bremner
                   ` (8 preceding siblings ...)
  2020-07-26 11:59 ` [PATCH 09/13] test: regression test for n_directory_{get,set}_mtime David Bremner
@ 2020-07-26 11:59 ` David Bremner
  2020-07-26 11:59 ` [PATCH 11/13] test: regression test for traversing config list with " David Bremner
                   ` (2 subsequent siblings)
  12 siblings, 0 replies; 17+ messages in thread
From: David Bremner @ 2020-07-26 11:59 UTC (permalink / raw)
  To: notmuch; +Cc: David Bremner

Exception is caught.
---
 test/T590-libconfig.sh | 15 +++++++++++++++
 1 file changed, 15 insertions(+)

diff --git a/test/T590-libconfig.sh b/test/T590-libconfig.sh
index 46f3a76d..602fad0b 100755
--- a/test/T590-libconfig.sh
+++ b/test/T590-libconfig.sh
@@ -61,6 +61,21 @@ valid = 0
 EOF
 test_expect_equal_file EXPECTED OUTPUT
 
+test_begin_subtest "notmuch_database_get_config_list: closed db"
+cat c_head - c_tail <<'EOF' | test_C ${MAIL_DIR}
+{
+   notmuch_config_list_t *list;
+   EXPECT0(notmuch_database_close (db));
+   stat = notmuch_database_get_config_list (db, "nonexistent", &list);
+   printf("%d\n", stat == NOTMUCH_STATUS_XAPIAN_EXCEPTION);
+}
+EOF
+cat <<'EOF' >EXPECTED
+== stdout ==
+1
+== stderr ==
+EOF
+test_expect_equal_file EXPECTED OUTPUT
 
 test_begin_subtest "notmuch_database_get_config_list: all pairs"
 cat c_head - c_tail <<'EOF' | test_C ${MAIL_DIR}
-- 
2.27.0

^ permalink raw reply related	[flat|nested] 17+ messages in thread

* [PATCH 11/13] test: regression test for traversing config list with closed db
  2020-07-26 11:59 final(?) batch of api cleanup for exception handling David Bremner
                   ` (9 preceding siblings ...)
  2020-07-26 11:59 ` [PATCH 10/13] test: regression test for n_d_get_config_list on closed db David Bremner
@ 2020-07-26 11:59 ` David Bremner
  2020-07-26 11:59 ` [PATCH 12/13] test: regression tests for n_indexopts_{get,set}_decrypt_policy David Bremner
  2020-07-26 11:59 ` [PATCH 13/13] lib: return NULL from n_d_get_default_indexopts on error David Bremner
  12 siblings, 0 replies; 17+ messages in thread
From: David Bremner @ 2020-07-26 11:59 UTC (permalink / raw)
  To: notmuch; +Cc: David Bremner

Also mention error return in API docs
---
 lib/notmuch.h          |  1 +
 test/T590-libconfig.sh | 22 ++++++++++++++++++++++
 2 files changed, 23 insertions(+)

diff --git a/lib/notmuch.h b/lib/notmuch.h
index d52fa976..1fe62914 100644
--- a/lib/notmuch.h
+++ b/lib/notmuch.h
@@ -2291,6 +2291,7 @@ notmuch_config_list_key (notmuch_config_list_t *config_list);
  * next call to notmuch_config_list_value or notmuch config_list_destroy
  *
  * @since libnotmuch 4.4 (notmuch 0.23)
+ * @retval NULL for errors
  */
 const char *
 notmuch_config_list_value (notmuch_config_list_t *config_list);
diff --git a/test/T590-libconfig.sh b/test/T590-libconfig.sh
index 602fad0b..360e45b0 100755
--- a/test/T590-libconfig.sh
+++ b/test/T590-libconfig.sh
@@ -100,6 +100,28 @@ zzzafter afterval
 EOF
 test_expect_equal_file EXPECTED OUTPUT
 
+test_begin_subtest "notmuch_database_get_config_list: all pairs (closed db)"
+cat c_head - c_tail <<'EOF' | test_C ${MAIL_DIR}
+{
+   notmuch_config_list_t *list;
+   EXPECT0(notmuch_database_get_config_list (db, "", &list));
+   EXPECT0(notmuch_database_close (db));
+   for (; notmuch_config_list_valid (list); notmuch_config_list_move_to_next (list)) {
+      printf("%s %d\n", notmuch_config_list_key (list), NULL == notmuch_config_list_value(list));
+   }
+   notmuch_config_list_destroy (list);
+}
+EOF
+cat <<'EOF' >EXPECTED
+== stdout ==
+aaabefore 1
+testkey1 1
+testkey2 1
+zzzafter 1
+== stderr ==
+EOF
+test_expect_equal_file EXPECTED OUTPUT
+
 test_begin_subtest "notmuch_database_get_config_list: one prefix"
 cat c_head - c_tail <<'EOF' | test_C ${MAIL_DIR}
 {
-- 
2.27.0

^ permalink raw reply related	[flat|nested] 17+ messages in thread

* [PATCH 12/13] test: regression tests for n_indexopts_{get,set}_decrypt_policy
  2020-07-26 11:59 final(?) batch of api cleanup for exception handling David Bremner
                   ` (10 preceding siblings ...)
  2020-07-26 11:59 ` [PATCH 11/13] test: regression test for traversing config list with " David Bremner
@ 2020-07-26 11:59 ` David Bremner
  2020-07-26 11:59 ` [PATCH 13/13] lib: return NULL from n_d_get_default_indexopts on error David Bremner
  12 siblings, 0 replies; 17+ messages in thread
From: David Bremner @ 2020-07-26 11:59 UTC (permalink / raw)
  To: notmuch; +Cc: David Bremner

The main criteria is that they don't crash. Working with a closed
database is a bonus.
---
 test/T562-lib-database.sh | 39 +++++++++++++++++++++++++++++++++++++++
 1 file changed, 39 insertions(+)

diff --git a/test/T562-lib-database.sh b/test/T562-lib-database.sh
index 32fda72e..815c9856 100755
--- a/test/T562-lib-database.sh
+++ b/test/T562-lib-database.sh
@@ -389,4 +389,43 @@ cat <<EOF > EXPECTED
 EOF
 test_expect_equal_file EXPECTED OUTPUT
 
+test_begin_subtest "get decryption policy from closed database"
+cat c_head - c_tail <<'EOF' | test_C ${MAIL_DIR}
+    {
+        notmuch_indexopts_t *result;
+        result = notmuch_database_get_default_indexopts (db);
+        EXPECT0(notmuch_database_close (db));
+        notmuch_decryption_policy_t policy = notmuch_indexopts_get_decrypt_policy (result);
+        printf ("%d\n",  policy == NOTMUCH_DECRYPT_AUTO);
+        notmuch_indexopts_destroy (result);
+        printf ("SUCCESS\n");
+    }
+EOF
+cat <<EOF > EXPECTED
+== stdout ==
+1
+SUCCESS
+== stderr ==
+EOF
+test_expect_equal_file EXPECTED OUTPUT
+
+test_begin_subtest "set decryption policy with closed database"
+cat c_head - c_tail <<'EOF' | test_C ${MAIL_DIR}
+    {
+        notmuch_indexopts_t *result;
+        result = notmuch_database_get_default_indexopts (db);
+        EXPECT0(notmuch_database_close (db));
+        notmuch_decryption_policy_t policy = notmuch_indexopts_get_decrypt_policy (result);
+        stat = notmuch_indexopts_set_decrypt_policy (result, policy);
+        printf("%d\n%d\n",  policy == NOTMUCH_DECRYPT_AUTO, stat == NOTMUCH_STATUS_SUCCESS);
+    }
+EOF
+cat <<EOF > EXPECTED
+== stdout ==
+1
+1
+== stderr ==
+EOF
+test_expect_equal_file EXPECTED OUTPUT
+
 test_done
-- 
2.27.0

^ permalink raw reply related	[flat|nested] 17+ messages in thread

* [PATCH 13/13] lib: return NULL from n_d_get_default_indexopts on error
  2020-07-26 11:59 final(?) batch of api cleanup for exception handling David Bremner
                   ` (11 preceding siblings ...)
  2020-07-26 11:59 ` [PATCH 12/13] test: regression tests for n_indexopts_{get,set}_decrypt_policy David Bremner
@ 2020-07-26 11:59 ` David Bremner
  12 siblings, 0 replies; 17+ messages in thread
From: David Bremner @ 2020-07-26 11:59 UTC (permalink / raw)
  To: notmuch; +Cc: David Bremner

This is a rare and probably serious programming error, so better not
to silently return a default value.
---
 lib/indexopts.c           | 2 +-
 lib/notmuch.h             | 1 +
 test/T562-lib-database.sh | 1 -
 3 files changed, 2 insertions(+), 2 deletions(-)

diff --git a/lib/indexopts.c b/lib/indexopts.c
index 1e8d180e..82a0026f 100644
--- a/lib/indexopts.c
+++ b/lib/indexopts.c
@@ -32,7 +32,7 @@ notmuch_database_get_default_indexopts (notmuch_database_t *db)
     char *decrypt_policy;
     notmuch_status_t err = notmuch_database_get_config (db, "index.decrypt", &decrypt_policy);
     if (err)
-	return ret;
+	return NULL;
 
     if (decrypt_policy) {
 	if ((! (strcasecmp (decrypt_policy, "true"))) ||
diff --git a/lib/notmuch.h b/lib/notmuch.h
index 1fe62914..f3cb0fe2 100644
--- a/lib/notmuch.h
+++ b/lib/notmuch.h
@@ -2325,6 +2325,7 @@ notmuch_config_list_destroy (notmuch_config_list_t *config_list);
  * added to the index.  At the moment it is a featureless stub.
  *
  * @since libnotmuch 5.1 (notmuch 0.26)
+ * @retval NULL in case of error
  */
 notmuch_indexopts_t *
 notmuch_database_get_default_indexopts (notmuch_database_t *db);
diff --git a/test/T562-lib-database.sh b/test/T562-lib-database.sh
index 815c9856..d6097418 100755
--- a/test/T562-lib-database.sh
+++ b/test/T562-lib-database.sh
@@ -373,7 +373,6 @@ EOF
 test_expect_equal_file EXPECTED OUTPUT
 
 test_begin_subtest "get indexopts from closed database"
-test_subtest_known_broken
 cat c_head - c_tail <<'EOF' | test_C ${MAIL_DIR}
     {
         notmuch_indexopts_t *result;
-- 
2.27.0

^ permalink raw reply related	[flat|nested] 17+ messages in thread

* [PATCH 1/2] test: known broken test for n_directory_delete with closed db.
  2020-07-26 11:59 ` [PATCH 08/13] test: regression test for n_directory_delete with closed db David Bremner
@ 2020-07-27  0:55   ` David Bremner
  2020-07-27  0:55     ` [PATCH 2/2] lib: fix return value for n_directory_delete David Bremner
  2020-07-27 12:06   ` [PATCH 08/13] test: regression test for n_directory_delete with closed db David Bremner
  1 sibling, 1 reply; 17+ messages in thread
From: David Bremner @ 2020-07-27  0:55 UTC (permalink / raw)
  To: David Bremner, notmuch

There is a return value bug in notmuch_directory_delete that is hiding
the exception.
---
 Well that was embarrassing. Silly bug in notmuch code, nothing to do with Xapian.
 
 test/T563-lib-directory.sh | 38 +++++++++++++++++++++++++++++++++++++-
 1 file changed, 37 insertions(+), 1 deletion(-)

diff --git a/test/T563-lib-directory.sh b/test/T563-lib-directory.sh
index 739469a6..8777f62b 100755
--- a/test/T563-lib-directory.sh
+++ b/test/T563-lib-directory.sh
@@ -26,7 +26,7 @@ int main (int argc, char** argv)
      exit (1);
    }
 
-   EXPECT0(notmuch_database_get_directory (db, "", &dir));
+   EXPECT0(notmuch_database_get_directory (db, "bar", &dir));
    EXPECT0(notmuch_database_close (db));
 EOF
 
@@ -74,4 +74,40 @@ A Xapian exception occurred at lib/directory.cc:XXX: Database has been closed
 EOF
 test_expect_equal_file EXPECTED OUTPUT
 
+backup_database
+test_begin_subtest "delete directory document for a closed db"
+test_subtest_known_broken
+cat c_head - c_tail <<'EOF' | test_C ${MAIL_DIR}
+    {
+        stat = notmuch_directory_delete (dir);
+        printf ("%d\n", stat == NOTMUCH_STATUS_XAPIAN_EXCEPTION);
+    }
+EOF
+cat <<EOF > EXPECTED
+== stdout ==
+1
+== stderr ==
+A Xapian exception occurred deleting directory entry: Database has been closed.
+EOF
+test_expect_equal_file EXPECTED OUTPUT
+restore_database
+
+backup_database
+test_begin_subtest "get/set mtime of directory for a closed db"
+cat c_head - c_tail <<'EOF' | test_C ${MAIL_DIR}
+    {
+        time_t stamp = notmuch_directory_get_mtime (dir);
+        stat = notmuch_directory_set_mtime (dir, stamp);
+        printf ("%d\n", stat == NOTMUCH_STATUS_XAPIAN_EXCEPTION);
+    }
+EOF
+cat <<EOF > EXPECTED
+== stdout ==
+1
+== stderr ==
+A Xapian exception occurred setting directory mtime: Database has been closed.
+EOF
+test_expect_equal_file EXPECTED OUTPUT
+restore_database
+
 test_done
-- 
2.27.0

^ permalink raw reply related	[flat|nested] 17+ messages in thread

* [PATCH 2/2] lib: fix return value for n_directory_delete
  2020-07-27  0:55   ` [PATCH 1/2] test: known broken " David Bremner
@ 2020-07-27  0:55     ` David Bremner
  0 siblings, 0 replies; 17+ messages in thread
From: David Bremner @ 2020-07-27  0:55 UTC (permalink / raw)
  To: David Bremner, notmuch

Falling out of the catch meant the error return was lost
---
 lib/directory.cc | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/lib/directory.cc b/lib/directory.cc
index 044cd680..37973c09 100644
--- a/lib/directory.cc
+++ b/lib/directory.cc
@@ -308,7 +308,7 @@ notmuch_directory_get_child_directories (notmuch_directory_t *directory)
 notmuch_status_t
 notmuch_directory_delete (notmuch_directory_t *directory)
 {
-    notmuch_status_t status;
+    notmuch_status_t status = NOTMUCH_STATUS_SUCCESS;
     Xapian::WritableDatabase *db;
 
     status = _notmuch_database_ensure_writable (directory->notmuch);
@@ -327,7 +327,7 @@ notmuch_directory_delete (notmuch_directory_t *directory)
     }
     notmuch_directory_destroy (directory);
 
-    return NOTMUCH_STATUS_SUCCESS;
+    return status;
 }
 
 void
-- 
2.27.0

^ permalink raw reply related	[flat|nested] 17+ messages in thread

* Re: [PATCH 08/13] test: regression test for n_directory_delete with closed db.
  2020-07-26 11:59 ` [PATCH 08/13] test: regression test for n_directory_delete with closed db David Bremner
  2020-07-27  0:55   ` [PATCH 1/2] test: known broken " David Bremner
@ 2020-07-27 12:06   ` David Bremner
  1 sibling, 0 replies; 17+ messages in thread
From: David Bremner @ 2020-07-27 12:06 UTC (permalink / raw)
  To: notmuch

David Bremner <david@tethera.net> writes:

> To the best of my current understanding, it's a bug in Xapian that no
> exception is thrown here. The test should pass in either case.
> ---
>  test/T563-lib-directory.sh | 19 ++++++++++++++++++-
>  1 file changed, 18 insertions(+), 1 deletion(-)
>
> diff --git a/test/T563-lib-directory.sh b/test/T563-lib-directory.sh
> index 739469a6..4de31078 100755
> --- a/test/T563-lib-directory.sh
> +++ b/test/T563-lib-directory.sh
> @@ -26,7 +26,7 @@ int main (int argc, char** argv)
>       exit (1);
>     }
>  
> -   EXPECT0(notmuch_database_get_directory (db, "", &dir));
> +   EXPECT0(notmuch_database_get_directory (db, "bar", &dir));
>     EXPECT0(notmuch_database_close (db));
>  EOF
note to self. That change should be in the earlier commit that
introduces this particular bit of test scaffolding.

^ permalink raw reply	[flat|nested] 17+ messages in thread

end of thread, other threads:[~2020-07-27 12:06 UTC | newest]

Thread overview: 17+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2020-07-26 11:59 final(?) batch of api cleanup for exception handling David Bremner
2020-07-26 11:59 ` [PATCH 01/13] test: add regression test for n_messages_collect_tags David Bremner
2020-07-26 11:59 ` [PATCH 02/13] test: split header for lib-message tests David Bremner
2020-07-26 11:59 ` [PATCH 03/13] test: regression test for n_m_get_filenames David Bremner
2020-07-26 11:59 ` [PATCH 04/13] test: add known broken test for n_directory_get_child_directories David Bremner
2020-07-26 11:59 ` [PATCH 05/13] lib: catch exceptions in n_directory_get_child_directories David Bremner
2020-07-26 11:59 ` [PATCH 06/13] test: add known broken test for n_directory_get_child_files David Bremner
2020-07-26 11:59 ` [PATCH 07/13] lib: catch exceptions in n_directory_get_child_files David Bremner
2020-07-26 11:59 ` [PATCH 08/13] test: regression test for n_directory_delete with closed db David Bremner
2020-07-27  0:55   ` [PATCH 1/2] test: known broken " David Bremner
2020-07-27  0:55     ` [PATCH 2/2] lib: fix return value for n_directory_delete David Bremner
2020-07-27 12:06   ` [PATCH 08/13] test: regression test for n_directory_delete with closed db David Bremner
2020-07-26 11:59 ` [PATCH 09/13] test: regression test for n_directory_{get,set}_mtime David Bremner
2020-07-26 11:59 ` [PATCH 10/13] test: regression test for n_d_get_config_list on closed db David Bremner
2020-07-26 11:59 ` [PATCH 11/13] test: regression test for traversing config list with " David Bremner
2020-07-26 11:59 ` [PATCH 12/13] test: regression tests for n_indexopts_{get,set}_decrypt_policy David Bremner
2020-07-26 11:59 ` [PATCH 13/13] lib: return NULL from n_d_get_default_indexopts on error David Bremner

Code repositories for project(s) associated with this public inbox

	https://yhetil.org/notmuch.git/

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).