aboutsummaryrefslogtreecommitdiff
path: root/llvm_tools/patch_utils_unittest.py
diff options
context:
space:
mode:
Diffstat (limited to 'llvm_tools/patch_utils_unittest.py')
-rwxr-xr-xllvm_tools/patch_utils_unittest.py368
1 files changed, 190 insertions, 178 deletions
diff --git a/llvm_tools/patch_utils_unittest.py b/llvm_tools/patch_utils_unittest.py
index 04541ae0..54c38763 100755
--- a/llvm_tools/patch_utils_unittest.py
+++ b/llvm_tools/patch_utils_unittest.py
@@ -16,87 +16,90 @@ import patch_utils as pu
class TestPatchUtils(unittest.TestCase):
- """Test the patch_utils."""
-
- def test_atomic_write(self):
- """Test that atomic write safely writes."""
- prior_contents = 'This is a test written by patch_utils_unittest.py\n'
- new_contents = 'I am a test written by patch_utils_unittest.py\n'
- with tempfile.TemporaryDirectory(prefix='patch_utils_unittest') as dirname:
- dirpath = Path(dirname)
- filepath = dirpath / 'test_atomic_write.txt'
- with filepath.open('w', encoding='utf-8') as f:
- f.write(prior_contents)
-
- def _t():
- with pu.atomic_write(filepath, encoding='utf-8') as f:
- f.write(new_contents)
- raise Exception('Expected failure')
-
- self.assertRaises(Exception, _t)
- with filepath.open(encoding='utf-8') as f:
- lines = f.readlines()
- self.assertEqual(lines[0], prior_contents)
- with pu.atomic_write(filepath, encoding='utf-8') as f:
- f.write(new_contents)
- with filepath.open(encoding='utf-8') as f:
- lines = f.readlines()
- self.assertEqual(lines[0], new_contents)
-
- def test_from_to_dict(self):
- """Test to and from dict conversion."""
- d = TestPatchUtils._default_json_dict()
- d['metadata'] = {
- 'title': 'hello world',
- 'info': [],
- 'other_extra_info': {
- 'extra_flags': [],
+ """Test the patch_utils."""
+
+ def test_atomic_write(self):
+ """Test that atomic write safely writes."""
+ prior_contents = "This is a test written by patch_utils_unittest.py\n"
+ new_contents = "I am a test written by patch_utils_unittest.py\n"
+ with tempfile.TemporaryDirectory(
+ prefix="patch_utils_unittest"
+ ) as dirname:
+ dirpath = Path(dirname)
+ filepath = dirpath / "test_atomic_write.txt"
+ with filepath.open("w", encoding="utf-8") as f:
+ f.write(prior_contents)
+
+ def _t():
+ with pu.atomic_write(filepath, encoding="utf-8") as f:
+ f.write(new_contents)
+ raise Exception("Expected failure")
+
+ self.assertRaises(Exception, _t)
+ with filepath.open(encoding="utf-8") as f:
+ lines = f.readlines()
+ self.assertEqual(lines[0], prior_contents)
+ with pu.atomic_write(filepath, encoding="utf-8") as f:
+ f.write(new_contents)
+ with filepath.open(encoding="utf-8") as f:
+ lines = f.readlines()
+ self.assertEqual(lines[0], new_contents)
+
+ def test_from_to_dict(self):
+ """Test to and from dict conversion."""
+ d = TestPatchUtils._default_json_dict()
+ d["metadata"] = {
+ "title": "hello world",
+ "info": [],
+ "other_extra_info": {
+ "extra_flags": [],
+ },
}
- }
- e = pu.PatchEntry.from_dict(TestPatchUtils._mock_dir(), d)
- self.assertEqual(d, e.to_dict())
-
- def test_patch_path(self):
- """Test that we can get the full path from a PatchEntry."""
- d = TestPatchUtils._default_json_dict()
- with mock.patch.object(Path, 'is_dir', return_value=True):
- entry = pu.PatchEntry.from_dict(Path('/home/dir'), d)
- self.assertEqual(entry.patch_path(),
- Path('/home/dir') / d['rel_patch_path'])
-
- def test_can_patch_version(self):
- """Test that patch application based on version is correct."""
- base_dict = TestPatchUtils._default_json_dict()
- workdir = TestPatchUtils._mock_dir()
- e1 = pu.PatchEntry.from_dict(workdir, base_dict)
- self.assertFalse(e1.can_patch_version(3))
- self.assertTrue(e1.can_patch_version(4))
- self.assertTrue(e1.can_patch_version(5))
- self.assertFalse(e1.can_patch_version(9))
- base_dict['version_range'] = {'until': 9}
- e2 = pu.PatchEntry.from_dict(workdir, base_dict)
- self.assertTrue(e2.can_patch_version(0))
- self.assertTrue(e2.can_patch_version(5))
- self.assertFalse(e2.can_patch_version(9))
- base_dict['version_range'] = {'from': 4}
- e3 = pu.PatchEntry.from_dict(workdir, base_dict)
- self.assertFalse(e3.can_patch_version(3))
- self.assertTrue(e3.can_patch_version(5))
- self.assertTrue(e3.can_patch_version(1 << 31))
- base_dict['version_range'] = {'from': 4, 'until': None}
- e4 = pu.PatchEntry.from_dict(workdir, base_dict)
- self.assertFalse(e4.can_patch_version(3))
- self.assertTrue(e4.can_patch_version(5))
- self.assertTrue(e4.can_patch_version(1 << 31))
- base_dict['version_range'] = {'from': None, 'until': 9}
- e5 = pu.PatchEntry.from_dict(workdir, base_dict)
- self.assertTrue(e5.can_patch_version(0))
- self.assertTrue(e5.can_patch_version(5))
- self.assertFalse(e5.can_patch_version(9))
-
- def test_can_parse_from_json(self):
- """Test that patches be loaded from json."""
- json = """
+ e = pu.PatchEntry.from_dict(TestPatchUtils._mock_dir(), d)
+ self.assertEqual(d, e.to_dict())
+
+ def test_patch_path(self):
+ """Test that we can get the full path from a PatchEntry."""
+ d = TestPatchUtils._default_json_dict()
+ with mock.patch.object(Path, "is_dir", return_value=True):
+ entry = pu.PatchEntry.from_dict(Path("/home/dir"), d)
+ self.assertEqual(
+ entry.patch_path(), Path("/home/dir") / d["rel_patch_path"]
+ )
+
+ def test_can_patch_version(self):
+ """Test that patch application based on version is correct."""
+ base_dict = TestPatchUtils._default_json_dict()
+ workdir = TestPatchUtils._mock_dir()
+ e1 = pu.PatchEntry.from_dict(workdir, base_dict)
+ self.assertFalse(e1.can_patch_version(3))
+ self.assertTrue(e1.can_patch_version(4))
+ self.assertTrue(e1.can_patch_version(5))
+ self.assertFalse(e1.can_patch_version(9))
+ base_dict["version_range"] = {"until": 9}
+ e2 = pu.PatchEntry.from_dict(workdir, base_dict)
+ self.assertTrue(e2.can_patch_version(0))
+ self.assertTrue(e2.can_patch_version(5))
+ self.assertFalse(e2.can_patch_version(9))
+ base_dict["version_range"] = {"from": 4}
+ e3 = pu.PatchEntry.from_dict(workdir, base_dict)
+ self.assertFalse(e3.can_patch_version(3))
+ self.assertTrue(e3.can_patch_version(5))
+ self.assertTrue(e3.can_patch_version(1 << 31))
+ base_dict["version_range"] = {"from": 4, "until": None}
+ e4 = pu.PatchEntry.from_dict(workdir, base_dict)
+ self.assertFalse(e4.can_patch_version(3))
+ self.assertTrue(e4.can_patch_version(5))
+ self.assertTrue(e4.can_patch_version(1 << 31))
+ base_dict["version_range"] = {"from": None, "until": 9}
+ e5 = pu.PatchEntry.from_dict(workdir, base_dict)
+ self.assertTrue(e5.can_patch_version(0))
+ self.assertTrue(e5.can_patch_version(5))
+ self.assertFalse(e5.can_patch_version(9))
+
+ def test_can_parse_from_json(self):
+ """Test that patches be loaded from json."""
+ json = """
[
{
"metadata": {},
@@ -118,51 +121,56 @@ class TestPatchUtils(unittest.TestCase):
}
]
"""
- result = pu.json_to_patch_entries(Path(), io.StringIO(json))
- self.assertEqual(len(result), 4)
-
- def test_parsed_hunks(self):
- """Test that we can parse patch file hunks."""
- m = mock.mock_open(read_data=_EXAMPLE_PATCH)
-
- def mocked_open(self, *args, **kwargs):
- return m(self, *args, **kwargs)
-
- with mock.patch.object(Path, 'open', mocked_open):
- e = pu.PatchEntry.from_dict(TestPatchUtils._mock_dir(),
- TestPatchUtils._default_json_dict())
- hunk_dict = e.parsed_hunks()
-
- m.assert_called()
- filename1 = 'clang/lib/Driver/ToolChains/Clang.cpp'
- filename2 = 'llvm/lib/Passes/PassBuilder.cpp'
- self.assertEqual(set(hunk_dict.keys()), {filename1, filename2})
- hunk_list1 = hunk_dict[filename1]
- hunk_list2 = hunk_dict[filename2]
- self.assertEqual(len(hunk_list1), 1)
- self.assertEqual(len(hunk_list2), 2)
-
- def test_apply_when_patch_nonexistent(self):
- """Test that we error out when we try to apply a non-existent patch."""
- src_dir = TestPatchUtils._mock_dir('somewhere/llvm-project')
- patch_dir = TestPatchUtils._mock_dir()
- e = pu.PatchEntry.from_dict(patch_dir, TestPatchUtils._default_json_dict())
- with mock.patch('subprocess.run', mock.MagicMock()):
- self.assertRaises(RuntimeError, lambda: e.apply(src_dir))
-
- def test_apply_success(self):
- """Test that we can call apply."""
- src_dir = TestPatchUtils._mock_dir('somewhere/llvm-project')
- patch_dir = TestPatchUtils._mock_dir()
- e = pu.PatchEntry.from_dict(patch_dir, TestPatchUtils._default_json_dict())
- with mock.patch('pathlib.Path.is_file', return_value=True):
- with mock.patch('subprocess.run', mock.MagicMock()):
- result = e.apply(src_dir)
- self.assertTrue(result.succeeded)
-
- def test_parse_failed_patch_output(self):
- """Test that we can call parse `patch` output."""
- fixture = """
+ result = pu.json_to_patch_entries(Path(), io.StringIO(json))
+ self.assertEqual(len(result), 4)
+
+ def test_parsed_hunks(self):
+ """Test that we can parse patch file hunks."""
+ m = mock.mock_open(read_data=_EXAMPLE_PATCH)
+
+ def mocked_open(self, *args, **kwargs):
+ return m(self, *args, **kwargs)
+
+ with mock.patch.object(Path, "open", mocked_open):
+ e = pu.PatchEntry.from_dict(
+ TestPatchUtils._mock_dir(), TestPatchUtils._default_json_dict()
+ )
+ hunk_dict = e.parsed_hunks()
+
+ m.assert_called()
+ filename1 = "clang/lib/Driver/ToolChains/Clang.cpp"
+ filename2 = "llvm/lib/Passes/PassBuilder.cpp"
+ self.assertEqual(set(hunk_dict.keys()), {filename1, filename2})
+ hunk_list1 = hunk_dict[filename1]
+ hunk_list2 = hunk_dict[filename2]
+ self.assertEqual(len(hunk_list1), 1)
+ self.assertEqual(len(hunk_list2), 2)
+
+ def test_apply_when_patch_nonexistent(self):
+ """Test that we error out when we try to apply a non-existent patch."""
+ src_dir = TestPatchUtils._mock_dir("somewhere/llvm-project")
+ patch_dir = TestPatchUtils._mock_dir()
+ e = pu.PatchEntry.from_dict(
+ patch_dir, TestPatchUtils._default_json_dict()
+ )
+ with mock.patch("subprocess.run", mock.MagicMock()):
+ self.assertRaises(RuntimeError, lambda: e.apply(src_dir))
+
+ def test_apply_success(self):
+ """Test that we can call apply."""
+ src_dir = TestPatchUtils._mock_dir("somewhere/llvm-project")
+ patch_dir = TestPatchUtils._mock_dir()
+ e = pu.PatchEntry.from_dict(
+ patch_dir, TestPatchUtils._default_json_dict()
+ )
+ with mock.patch("pathlib.Path.is_file", return_value=True):
+ with mock.patch("subprocess.run", mock.MagicMock()):
+ result = e.apply(src_dir)
+ self.assertTrue(result.succeeded)
+
+ def test_parse_failed_patch_output(self):
+ """Test that we can call parse `patch` output."""
+ fixture = """
checking file a/b/c.cpp
Hunk #1 SUCCEEDED at 96 with fuzz 1.
Hunk #12 FAILED at 77.
@@ -172,59 +180,63 @@ Hunk #4 FAILED at 30.
checking file works.cpp
Hunk #1 SUCCEEDED at 96 with fuzz 1.
"""
- result = pu.parse_failed_patch_output(fixture)
- self.assertEqual(result['a/b/c.cpp'], [12, 42])
- self.assertEqual(result['x/y/z.h'], [4])
- self.assertNotIn('works.cpp', result)
-
- def test_is_git_dirty(self):
- """Test if a git directory has uncommitted changes."""
- with tempfile.TemporaryDirectory(prefix='patch_utils_unittest') as dirname:
- dirpath = Path(dirname)
-
- def _run_h(cmd):
- subprocess.run(cmd,
- cwd=dirpath,
- stdout=subprocess.DEVNULL,
- stderr=subprocess.DEVNULL,
- check=True)
-
- _run_h(['git', 'init'])
- self.assertFalse(pu.is_git_dirty(dirpath))
- test_file = dirpath / 'test_file'
- test_file.touch()
- self.assertTrue(pu.is_git_dirty(dirpath))
- _run_h(['git', 'add', '.'])
- _run_h(['git', 'commit', '-m', 'test'])
- self.assertFalse(pu.is_git_dirty(dirpath))
- test_file.touch()
- self.assertFalse(pu.is_git_dirty(dirpath))
- with test_file.open('w', encoding='utf-8'):
- test_file.write_text('abc')
- self.assertTrue(pu.is_git_dirty(dirpath))
-
- @staticmethod
- def _default_json_dict():
- return {
- 'metadata': {
- 'title': 'hello world',
- },
- 'platforms': ['a'],
- 'rel_patch_path': 'x/y/z',
- 'version_range': {
- 'from': 4,
- 'until': 9,
+ result = pu.parse_failed_patch_output(fixture)
+ self.assertEqual(result["a/b/c.cpp"], [12, 42])
+ self.assertEqual(result["x/y/z.h"], [4])
+ self.assertNotIn("works.cpp", result)
+
+ def test_is_git_dirty(self):
+ """Test if a git directory has uncommitted changes."""
+ with tempfile.TemporaryDirectory(
+ prefix="patch_utils_unittest"
+ ) as dirname:
+ dirpath = Path(dirname)
+
+ def _run_h(cmd):
+ subprocess.run(
+ cmd,
+ cwd=dirpath,
+ stdout=subprocess.DEVNULL,
+ stderr=subprocess.DEVNULL,
+ check=True,
+ )
+
+ _run_h(["git", "init"])
+ self.assertFalse(pu.is_git_dirty(dirpath))
+ test_file = dirpath / "test_file"
+ test_file.touch()
+ self.assertTrue(pu.is_git_dirty(dirpath))
+ _run_h(["git", "add", "."])
+ _run_h(["git", "commit", "-m", "test"])
+ self.assertFalse(pu.is_git_dirty(dirpath))
+ test_file.touch()
+ self.assertFalse(pu.is_git_dirty(dirpath))
+ with test_file.open("w", encoding="utf-8"):
+ test_file.write_text("abc")
+ self.assertTrue(pu.is_git_dirty(dirpath))
+
+ @staticmethod
+ def _default_json_dict():
+ return {
+ "metadata": {
+ "title": "hello world",
+ },
+ "platforms": ["a"],
+ "rel_patch_path": "x/y/z",
+ "version_range": {
+ "from": 4,
+ "until": 9,
+ },
}
- }
- @staticmethod
- def _mock_dir(path: str = 'a/b/c'):
- workdir = Path(path)
- workdir = mock.MagicMock(workdir)
- workdir.is_dir = lambda: True
- workdir.joinpath = lambda x: Path(path).joinpath(x)
- workdir.__truediv__ = lambda self, x: self.joinpath(x)
- return workdir
+ @staticmethod
+ def _mock_dir(path: str = "a/b/c"):
+ workdir = Path(path)
+ workdir = mock.MagicMock(workdir)
+ workdir.is_dir = lambda: True
+ workdir.joinpath = lambda x: Path(path).joinpath(x)
+ workdir.__truediv__ = lambda self, x: self.joinpath(x)
+ return workdir
_EXAMPLE_PATCH = """
@@ -272,5 +284,5 @@ index c5fd68299eb..4c6e15eeeb9 100644
// FIXME: It would seem like these should come first in the optimization
"""
-if __name__ == '__main__':
- unittest.main()
+if __name__ == "__main__":
+ unittest.main()