database error
[notmuch-archives.git] / 8d / a0212b9db3217768b40f22ec6ffcba8f9c4c14
1 Return-Path: <bremner@tethera.net>\r
2 X-Original-To: notmuch@notmuchmail.org\r
3 Delivered-To: notmuch@notmuchmail.org\r
4 Received: from localhost (localhost [127.0.0.1])\r
5  by arlo.cworth.org (Postfix) with ESMTP id 7ED086DE0243\r
6  for <notmuch@notmuchmail.org>; Sat,  2 Apr 2016 09:19:24 -0700 (PDT)\r
7 X-Virus-Scanned: Debian amavisd-new at cworth.org\r
8 X-Spam-Flag: NO\r
9 X-Spam-Score: -0.02\r
10 X-Spam-Level: \r
11 X-Spam-Status: No, score=-0.02 tagged_above=-999 required=5 tests=[AWL=-0.009,\r
12   SPF_PASS=-0.001, T_RP_MATCHES_RCVD=-0.01] autolearn=disabled\r
13 Received: from arlo.cworth.org ([127.0.0.1])\r
14  by localhost (arlo.cworth.org [127.0.0.1]) (amavisd-new, port 10024)\r
15  with ESMTP id 4cu-_GAnWwKx for <notmuch@notmuchmail.org>;\r
16  Sat,  2 Apr 2016 09:19:16 -0700 (PDT)\r
17 Received: from fethera.tethera.net (fethera.tethera.net [198.245.60.197])\r
18  by arlo.cworth.org (Postfix) with ESMTPS id 61F246DE02C2\r
19  for <notmuch@notmuchmail.org>; Sat,  2 Apr 2016 09:19:16 -0700 (PDT)\r
20 Received: from remotemail by fethera.tethera.net with local (Exim 4.84)\r
21  (envelope-from <bremner@tethera.net>)\r
22  id 1amOH5-0004fC-A4; Sat, 02 Apr 2016 12:19:47 -0400\r
23 Received: (nullmailer pid 13159 invoked by uid 1000);\r
24  Sat, 02 Apr 2016 16:19:11 -0000\r
25 From: David Bremner <david@tethera.net>\r
26 To: Daniel Kahn Gillmor <dkg@fifthhorseman.net>,\r
27  Notmuch Mail <notmuch@notmuchmail.org>\r
28 Subject: [PATCH 1/2] test thread breakage when messages are removed and\r
29  re-added\r
30 Date: Sat,  2 Apr 2016 13:19:01 -0300\r
31 Message-Id: <1459613942-13098-1-git-send-email-david@tethera.net>\r
32 X-Mailer: git-send-email 2.8.0.rc3\r
33 In-Reply-To: <1459606541-23889-1-git-send-email-dkg@fifthhorseman.net>\r
34 References: <1459606541-23889-1-git-send-email-dkg@fifthhorseman.net>\r
35 X-BeenThere: notmuch@notmuchmail.org\r
36 X-Mailman-Version: 2.1.20\r
37 Precedence: list\r
38 List-Id: "Use and development of the notmuch mail system."\r
39  <notmuch.notmuchmail.org>\r
40 List-Unsubscribe: <https://notmuchmail.org/mailman/options/notmuch>,\r
41  <mailto:notmuch-request@notmuchmail.org?subject=unsubscribe>\r
42 List-Archive: <http://notmuchmail.org/pipermail/notmuch/>\r
43 List-Post: <mailto:notmuch@notmuchmail.org>\r
44 List-Help: <mailto:notmuch-request@notmuchmail.org?subject=help>\r
45 List-Subscribe: <https://notmuchmail.org/mailman/listinfo/notmuch>,\r
46  <mailto:notmuch-request@notmuchmail.org?subject=subscribe>\r
47 X-List-Received-Date: Sat, 02 Apr 2016 16:19:24 -0000\r
48 \r
49 From: Daniel Kahn Gillmor <dkg@fifthhorseman.net>\r
50 \r
51 This test (T590-thread-breakage.sh) currently fails!\r
52 \r
53 If you have a two-message thread where message "B" is in-reply-to "A",\r
54 notmuch rightly sees this as a single thread.\r
55 \r
56 But if you:\r
57 \r
58  * remove "A" from the message store\r
59  * run "notmuch new"\r
60  * add "A" back into the message store\r
61  * re-run "notmuch new"\r
62 \r
63 Then notmuch sees the messages as distinct threads.\r
64 \r
65 I think this happens because if you insert "B" initially (before\r
66 anything is known about "A"), then a "ghost message" gets added to the\r
67 database in reference to "A" that is in the same thread, which "A"\r
68 takes over when it appears.\r
69 \r
70 But if "A" is subsequently removed, no ghost message is retained, so\r
71 when "A" appears, it is treated as a new thread.\r
72 \r
73 I don't know how to easily fix this, but i see a few options:\r
74 \r
75 ghost-on-removal\r
76 ----------------\r
77 \r
78 We could unilaterally add a ghost upon message removal.  This has a\r
79 few disadvantages: the message index would leak information about what\r
80 messages the user has ever been exposed to, and we also create a\r
81 perpetually-growing dataset -- the ghosts can never be removed.\r
82 \r
83 ghost-on-removal-when-shared-thread-exists\r
84 ------------------------------------------\r
85 \r
86 We could add a ghost upon message removal iff there are other\r
87 non-ghost messages with the same thread ID.\r
88 \r
89 We'd also need to remove all ghost messages that share a thread when\r
90 the last non-ghost message in that thread is removed.\r
91 \r
92 This still has a bit of information leakage, though: the message index\r
93 would reveal that i've seen a newer message in a thread, even if i had\r
94 deleted it from my message store\r
95 \r
96 track-dependencies\r
97 ------------------\r
98 \r
99 rather than a simple "ghost-message" we could store all the (A,B)\r
100 message-reference pairs internally, showing which messages A reference\r
101 which other messages B.\r
102 \r
103 Then removal of message X would require deleting all message-reference\r
104 pairs (X,B), and only deleting a ghost message if no (A,X) reference\r
105 pair exists.\r
106 \r
107 This requires modifying the database by adding a new and fairly weird\r
108 table that would need to be indexed by both columns.  I don't know\r
109 whether xapian has nice ways to do that.\r
110 \r
111 scan-dependencies\r
112 -----------------\r
113 \r
114 Without modifying the database, we could do something less efficient.\r
115 \r
116 Upon removal of message X, we could scan the headers of all non-ghost\r
117 messages that share a thread with X.  If any of those messages refers\r
118 to X, we would add a ghost message.  If none of them do, then we would\r
119 just drop X entirely from the table.\r
120 ---\r
121 \r
122 Here I just changed the FAILing test to BROKEN. This reflects our\r
123 usual distinction between known bug and regression.\r
124 \r
125  test/T590-thread-breakage.sh | 67 ++++++++++++++++++++++++++++++++++++++++++++\r
126  1 file changed, 67 insertions(+)\r
127  create mode 100755 test/T590-thread-breakage.sh\r
128 \r
129 diff --git a/test/T590-thread-breakage.sh b/test/T590-thread-breakage.sh\r
130 new file mode 100755\r
131 index 0000000..8c8e63b\r
132 --- /dev/null\r
133 +++ b/test/T590-thread-breakage.sh\r
134 @@ -0,0 +1,67 @@\r
135 +#!/usr/bin/env bash\r
136 +#\r
137 +# Copyright (c) 2016 Daniel Kahn Gillmor\r
138 +#\r
139 +\r
140 +test_description='thread breakage by reindexing (currently broken)'\r
141 +\r
142 +. ./test-lib.sh || exit 1\r
143 +\r
144 +message_a() {\r
145 +    mkdir -p ${MAIL_DIR}/cur\r
146 +    cat > ${MAIL_DIR}/cur/a <<EOF\r
147 +Subject: First message\r
148 +Message-ID: <a@example.net>\r
149 +From: Alice <alice@example.net>\r
150 +To: Bob <bob@example.net>\r
151 +Date: Thu, 31 Mar 2016 20:10:00 -0400\r
152 +\r
153 +This is the first message in the thread.\r
154 +EOF\r
155 +}\r
156 +\r
157 +message_b() {\r
158 +    mkdir -p ${MAIL_DIR}/cur\r
159 +    cat > ${MAIL_DIR}/cur/b <<EOF\r
160 +Subject: Second message\r
161 +Message-ID: <b@example.net>\r
162 +In-Reply-To: <a@example.net>\r
163 +References: <a@example.net>\r
164 +From: Bob <bob@example.net>\r
165 +To: Alice <alice@example.net>\r
166 +Date: Thu, 31 Mar 2016 20:15:00 -0400\r
167 +\r
168 +This is the second message in the thread.\r
169 +EOF\r
170 +}\r
171 +\r
172 +\r
173 +test_thread_count() {\r
174 +    notmuch new >/dev/null\r
175 +    test_begin_subtest "${2:-Expecting $1 thread(s)}"\r
176 +    count=$(notmuch count --output=threads)\r
177 +    test_expect_equal "$count" "$1"\r
178 +}\r
179 +\r
180 +test_thread_count 0 'There should be no threads initially'\r
181 +\r
182 +message_a\r
183 +test_thread_count 1 'One message in: one thread'\r
184 +\r
185 +message_b\r
186 +test_thread_count 1 'Second message in the same thread: one thread'\r
187 +\r
188 +rm -f ${MAIL_DIR}/cur/a\r
189 +test_thread_count 1 'First message removed: still only one thread'\r
190 +\r
191 +message_a\r
192 +# this is known to fail (it shows 2 threads) because no "ghost\r
193 +# message" was created for message A when it was removed from the\r
194 +# index, despite message B still pointing to it.\r
195 +test_begin_subtest 'First message reappears: should return to the same thread'\r
196 +test_subtest_known_broken\r
197 +notmuch new >/dev/null\r
198 +count=$(notmuch count --output=threads)\r
199 +test_expect_equal "$count" "1"\r
200 +\r
201 +test_done\r
202 -- \r
203 2.8.0.rc3\r
204 \r