Home Home > GIT Browse > scripts
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorBenjamin Poirier <bpoirier@suse.com>2018-06-21 16:58:17 +0900
committerBenjamin Poirier <bpoirier@suse.com>2018-08-23 16:58:08 +0900
commitb710f8d90e304eb7f64acb7105319b4e40df8970 (patch)
tree689aa73611fddee30d36cf1858ac5d616e276cbd
parent38de9a0a1c000a0e5abdef529ed19311acae2d19 (diff)
scripts/git_sort/patch.py: Fix detection of patch header end
Consider linux commit 1e047eaab3bb ("block/loop: fix deadlock after loop_set_status"), some lines from the log start with "---" but do not mark the end of the patch header. Fix the pattern matching to match what is done in quilt. Also add a test which triggers the issue.
-rw-r--r--scripts/git_sort/patch.py9
-rw-r--r--scripts/git_sort/tests/support.py5
-rwxr-xr-xscripts/git_sort/tests/test_quilt_mode.py152
3 files changed, 160 insertions, 6 deletions
diff --git a/scripts/git_sort/patch.py b/scripts/git_sort/patch.py
index 8dea434848..b400b5db0b 100644
--- a/scripts/git_sort/patch.py
+++ b/scripts/git_sort/patch.py
@@ -2,12 +2,17 @@
# -*- coding: utf-8 -*-
import io
+import re
import sys
import exc
class Patch(object):
+ # This pattern was copied from quilt/scripts/patchfns.in:patch_header() in
+ # the quilt sources
+ break_matcher = re.compile(b"(---|\*\*\*|Index:)[ \t][^ \t]|^diff -")
+
def __init__(self, f):
assert(f.tell() == 0)
assert(isinstance(f, io.BufferedIOBase)) # binary (bytes) io object
@@ -17,9 +22,7 @@ class Patch(object):
self.head = []
self.body = b""
for line in f:
- # These patterns were copied from
- # quilt/scripts/patchfns.in:patch_header() in the quilt sources
- if line.startswith((b"---", b"***", b"Index:", b"diff -",)):
+ if self.break_matcher.match(line):
self.body = line
break
self.head.append(line.decode())
diff --git a/scripts/git_sort/tests/support.py b/scripts/git_sort/tests/support.py
index 0e5febbd86..dfff2b855f 100644
--- a/scripts/git_sort/tests/support.py
+++ b/scripts/git_sort/tests/support.py
@@ -56,7 +56,8 @@ def format_sanitized_subject(message):
return "".join(result[:52])
-def format_patch(commit, mainline=None, repo=None, directory=""):
+def format_patch(commit, mainline=None, repo=None, references=None,
+ directory=""):
name = os.path.join(directory, format_sanitized_subject(commit.message) +
".patch")
@@ -74,6 +75,8 @@ def format_patch(commit, mainline=None, repo=None, directory=""):
f.write("Git-commit: %s\n" % (str(commit.id),))
else:
f.write("Patch-mainline: No\n")
+ if references is not None:
+ f.write("References: %s\n" % (references,))
f.write("Subject: %s" % (commit.message,))
if not commit.message.endswith("\n"):
f.write("\n")
diff --git a/scripts/git_sort/tests/test_quilt_mode.py b/scripts/git_sort/tests/test_quilt_mode.py
index 4967c5e761..95f35a74b4 100755
--- a/scripts/git_sort/tests/test_quilt_mode.py
+++ b/scripts/git_sort/tests/test_quilt_mode.py
@@ -25,7 +25,6 @@ class TestQuiltMode(unittest.TestCase):
self.repo = pygit2.init_repository(os.environ["LINUX_GIT"])
self.repo.config["user.email"] = "agraf@suse.de"
self.repo.config["user.name"] = "Alexander Graf"
- readme_path = os.path.join(os.environ["LINUX_GIT"], "README")
author = pygit2.Signature("Alice Author", "alice@authors.tld")
committer = pygit2.Signature("Cecil Committer", "cecil@committers.tld")
@@ -572,7 +571,156 @@ class TestMergeTool(unittest.TestCase):
self.assertEqual(retval.decode().strip(), "M series.conf")
+class TestQCP(unittest.TestCase):
+ def setUp(self):
+ os.environ["XDG_CACHE_HOME"] = tempfile.mkdtemp(prefix="gs_cache")
+
+ # setup stub linux repository
+ os.environ["LINUX_GIT"] = tempfile.mkdtemp(prefix="gs_repo")
+ self.repo = pygit2.init_repository(os.environ["LINUX_GIT"])
+ self.repo.config["user.email"] = "author1@example.com"
+ self.repo.config["user.name"] = "Author One"
+
+ author = pygit2.Signature("Author One", "author1@example.com")
+ committer = pygit2.Signature("Maintainer One", "maintainer1@example.com")
+ tree = self.repo.TreeBuilder()
+
+ tree.insert("driver.c",
+ self.repo.create_blob("#include <bad.h>\n"),
+ pygit2.GIT_FILEMODE_BLOB)
+ self.commits = []
+ self.commits.append(self.repo.create_commit(
+ "refs/heads/mainline",
+ author,
+ committer,
+ """Add a very small module
+
+... which was not tested.
+
+Signed-off-by: Author One <author1@example.com>
+Signed-off-by: Maintainer One <maintainer@example.com>
+""",
+ tree.write(),
+ []
+ ))
+
+ tree.insert("driver.c",
+ self.repo.create_blob("#include <linux/module.h>\n"),
+ pygit2.GIT_FILEMODE_BLOB)
+ self.commits.append(self.repo.create_commit(
+ "refs/heads/mainline",
+ author,
+ committer,
+ """Fix the very small module
+
+syzbot is reporting deadlocks at __blkdev_get() [1].
+
+----------------------------------------
+[ 92.493919] systemd-udevd D12696 525 1 0x00000000
+[ 92.495891] Call Trace:
+[ 92.501560] schedule+0x23/0x80
+[ 92.502923] schedule_preempt_disabled+0x5/0x10
+[ 92.504645] __mutex_lock+0x416/0x9e0
+[ 92.510760] __blkdev_get+0x73/0x4f0
+[ 92.512220] blkdev_get+0x12e/0x390
+[ 92.518151] do_dentry_open+0x1c3/0x2f0
+[ 92.519815] path_openat+0x5d9/0xdc0
+[ 92.521437] do_filp_open+0x7d/0xf0
+[ 92.527365] do_sys_open+0x1b8/0x250
+[ 92.528831] do_syscall_64+0x6e/0x270
+[ 92.530341] entry_SYSCALL_64_after_hwframe+0x42/0xb7
+
+[ 92.931922] 1 lock held by systemd-udevd/525:
+[ 92.933642] #0: 00000000a2849e25 (&bdev->bd_mutex){+.+.}, at: __blkdev_get+0x73/0x4f0
+----------------------------------------
+
+The reason of deadlock turned out that wait_event_interruptible() in
+
+Reported-by: Markus Trippelsdorf <markus@trippelsdorf.de>
+Fixes: %s ("Add a very small module")
+Signed-off-by: Author One <author1@example.com>
+Signed-off-by: Maintainer One <maintainer@example.com>
+""" % (str(self.commits[-1],)),
+ tree.write(),
+ [self.commits[-1]]
+ ))
+
+ self.repo.create_tag("v4.10-rc6", self.commits[-1], pygit2.GIT_REF_OID,
+ committer, "Linux 4.10-rc6")
+
+ self.repo.remotes.create(
+ "origin",
+ "git://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git")
+ self.repo.references.create("refs/remotes/origin/master",
+ self.commits[-1])
+
+ # setup stub kernel-source content
+ self.ks_dir = tempfile.mkdtemp(prefix="gs_ks")
+ patch_dir = os.path.join(self.ks_dir, "patches.suse")
+ os.mkdir(patch_dir)
+ os.chdir(patch_dir)
+ with open(os.path.join(self.ks_dir, "series.conf"), mode="w") as f:
+ f.write(
+"""# Kernel patches configuration file
+
+ ########################################################
+ # sorted patches
+ ########################################################
+""")
+ f.write("\tpatches.suse/%s\n" % (
+ tests.support.format_patch(self.repo.get(self.commits[0]),
+ mainline="v4.9",
+ references="bsc#123"),))
+ f.write(
+"""
+ ########################################################
+ # end of sorted patches
+ ########################################################
+""")
+
+ ss_path = os.path.join(lib.libdir(), "series_sort.py")
+ os.chdir(self.ks_dir)
+
+ # This overlaps what is tested by test_series_sort, hence, not put in a
+ # test of its own.
+ subprocess.check_call([ss_path, "-c", "series.conf"])
+ with open("series.conf") as f:
+ content1 = f.read()
+ subprocess.check_call([ss_path, "series.conf"])
+ with open("series.conf") as f:
+ content2 = f.read()
+ self.assertEqual(content2, content1)
+
+ os.makedirs("tmp/current")
+ os.chdir("tmp/current")
+ subprocess.check_call(
+ ["quilt", "setup", "--sourcedir", "../../", "../../series.conf"])
+
+
+ def tearDown(self):
+ shutil.rmtree(os.environ["XDG_CACHE_HOME"])
+ shutil.rmtree(os.environ["LINUX_GIT"])
+ shutil.rmtree(self.ks_dir)
+
+
+ def test_fixup(self):
+ qm_path = os.path.join(lib.libdir(), "quilt-mode.sh")
+
+ # import commits[1]
+ subprocess.check_call(
+ ". %s; qgoto %s" % (qm_path, str(self.commits[1])), shell=True,
+ stdout=subprocess.DEVNULL, executable="/bin/bash")
+ subprocess.check_call(
+ """. %s; qcp -f %s""" % (
+ qm_path, str(self.commits[1])),
+ shell=True, stdout=subprocess.DEVNULL, executable="/bin/bash")
+
+ retval = subprocess.check_output(("quilt", "--quiltrc", "-", "next",))
+ name = "patches.suse/Fix-the-very-small-module.patch"
+ self.assertEqual(retval.decode().strip(), name)
+
+
if __name__ == '__main__':
# Run a single testcase
- suite = unittest.TestLoader().loadTestsFromTestCase(TestMergeTool)
+ suite = unittest.TestLoader().loadTestsFromTestCase(TestQCP)
unittest.TextTestRunner(verbosity=2).run(suite)