[PATCH b4 2/2] tests: exercise naked cover-letter detection

Christian Brauner <[email protected]> Wed, 01 Jul 2026 15:51:22 +0200
Newsgroups org.kernel.linux.tools
Message-ID <[email protected]>
Add fixtures and a test for the naked cover-letter fallback in
get_series().

The positive fixture is a single-patch series whose cover has neither a
[PATCH 0/N] prefix nor a diffstat; get_series() must still recognize it
as the cover via the same-author thread-root rule.

The negative fixture is a patch sent in-reply-to a third party's bug
report; that report must not be mistaken for a cover letter, so
has_cover stays False and patches[0] is None.

Signed-off-by: Christian Brauner (Amutable) <[email protected]>
---
 src/tests/samples/naked-cover-bugreport.mbox | 47 ++++++++++++++++++++++++++++
 src/tests/samples/naked-cover-single.mbox    | 44 ++++++++++++++++++++++++++
 src/tests/test___init__.py                   | 32 +++++++++++++++++++
 3 files changed, 123 insertions(+)

diff --git a/src/tests/samples/naked-cover-bugreport.mbox b/src/tests/samples/naked-cover-bugreport.mbox
new file mode 100644
index 0000000..17dd29b
--- /dev/null
+++ b/src/tests/samples/naked-cover-bugreport.mbox
@@ -0,0 +1,47 @@
+From mboxrd@git Thu Jan  1 00:00:00 1970
+Subject: widget subsystem corrupts data under load
+MIME-Version: 1.0
+Content-Type: text/plain; charset="utf-8"
+Content-Transfer-Encoding: 8bit
+From: Bug Reporter <[email protected]>
+Date: Tue, 25 Oct 2022 13:38:41 -0400
+Message-Id: <[email protected]>
+To: [email protected]
+
+Hi,
+
+I am seeing data corruption in the widget subsystem under load.  This
+report has no diffstat and no [PATCH 0/N] prefix, and it was written by
+somebody other than the patch author, so it must not be mistaken for a
+cover letter.
+
+From mboxrd@git Thu Jan  1 00:00:00 1970
+Subject: [PATCH] widget: fix data corruption under load
+MIME-Version: 1.0
+Content-Type: text/plain; charset="utf-8"
+Content-Transfer-Encoding: 8bit
+From: Test Author <[email protected]>
+Date: Tue, 25 Oct 2022 13:38:42 -0400
+Message-Id: <[email protected]>
+In-Reply-To: <[email protected]>
+References: <[email protected]>
+To: [email protected]
+Cc: Bug Reporter <[email protected]>
+
+Take the lock before touching the shared widget state.
+
+Reported-by: Bug Reporter <[email protected]>
+Signed-off-by: Test Author <[email protected]>
+---
+ file1 | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/file1 b/file1
+index 0000001..0000002 100644
+--- a/file1
++++ b/file1
+@@ -1,3 +1,3 @@
+ line 1
+-line 2
++line two
+ line 3
diff --git a/src/tests/samples/naked-cover-single.mbox b/src/tests/samples/naked-cover-single.mbox
new file mode 100644
index 0000000..fa7baad
--- /dev/null
+++ b/src/tests/samples/naked-cover-single.mbox
@@ -0,0 +1,44 @@
+From mboxrd@git Thu Jan  1 00:00:00 1970
+Subject: do a thing to the widget subsystem
+MIME-Version: 1.0
+Content-Type: text/plain; charset="utf-8"
+Content-Transfer-Encoding: 8bit
+From: Test Author <[email protected]>
+Date: Tue, 25 Oct 2022 13:38:41 -0400
+Message-Id: <[email protected]>
+To: [email protected]
+
+Hi all,
+
+this changes how the widget works.  Note that there is neither a
+[PATCH 0/N] prefix nor a diffstat on this cover letter, yet it is
+still a genuine cover letter for the single patch that follows.
+
+From mboxrd@git Thu Jan  1 00:00:00 1970
+Subject: [PATCH] widget: do the thing
+MIME-Version: 1.0
+Content-Type: text/plain; charset="utf-8"
+Content-Transfer-Encoding: 8bit
+From: Test Author <[email protected]>
+Date: Tue, 25 Oct 2022 13:38:42 -0400
+Message-Id: <[email protected]>
+In-Reply-To: <[email protected]>
+References: <[email protected]>
+To: [email protected]
+
+Make the widget finally do the thing it was always meant to do.
+
+Signed-off-by: Test Author <[email protected]>
+---
+ file1 | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/file1 b/file1
+index 0000001..0000002 100644
+--- a/file1
++++ b/file1
+@@ -1,3 +1,3 @@
+ line 1
+-line 2
++line two
+ line 3
diff --git a/src/tests/test___init__.py b/src/tests/test___init__.py
index cb34d1f..f9deb5d 100644
--- a/src/tests/test___init__.py
+++ b/src/tests/test___init__.py
@@ -393,6 +393,38 @@ def test_followup_trailers(
         assert ifh.getvalue().decode() == fh.read()
 
 
[email protected](
+    'source,expect_cover,expect_subject',
+    [
+        # A cover with neither a [PATCH 0/N] prefix nor a diffstat is still
+        # recognized when it is the same-author thread root of the series.
+        ('single', True, 'do a thing to the widget subsystem'),
+        # A patch sent in-reply-to someone else's bug report must not mistake
+        # that report for a cover letter.
+        ('bugreport', False, None),
+    ],
+)
+def test_naked_cover_letter_detection(
+    sampledir: str,
+    source: str,
+    expect_cover: bool,
+    expect_subject: Optional[str],
+) -> None:
+    lmbx = b4.LoreMailbox()
+    for msg in b4.get_msgs_from_mailbox_or_maildir(
+        f'{sampledir}/naked-cover-{source}.mbox'
+    ):
+        lmbx.add_message(msg)
+    lser = lmbx.get_series(codereview_trailers=False)
+    assert lser is not None
+    assert lser.has_cover is expect_cover
+    if expect_subject is None:
+        assert lser.patches[0] is None
+    else:
+        assert lser.patches[0] is not None
+        assert lser.patches[0].subject == expect_subject
+
+
 @pytest.mark.parametrize(
     'hval,verify,tr',
     [

-- 
2.53.0