Browse Source

Add patch duplication test

Fixes #958
Eloston 4 years ago
parent
commit
4679001429

+ 22 - 0
devutils/.coveragerc

@@ -0,0 +1,22 @@
+[run]
+branch = True
+parallel = True
+omit = tests/*
+
+[report]
+# Regexes for lines to exclude from consideration
+exclude_lines =
+    # Have to re-enable the standard pragma
+    pragma: no cover
+
+    # Don't complain about missing debug-only code:
+    def __repr__
+    if self\.debug
+
+    # Don't complain if tests don't hit defensive assertion code:
+    raise AssertionError
+    raise NotImplementedError
+
+    # Don't complain if non-runnable code isn't run:
+    if 0:
+    if __name__ == .__main__.:

+ 0 - 0
devutils/__init__.py


+ 19 - 1
devutils/check_patch_files.py

@@ -75,7 +75,7 @@ def check_unused_patches(patches_dir, series_path=Path('series')):
         Unused patches are logged to stdout.
 
     patches_dir is a pathlib.Path to the directory of patches
-    series_path is a pathlib.Path to the series file relative to the patch_dir
+    series_path is a pathlib.Path to the series file relative to the patches_dir
 
     Returns True if there are unused patches; False otherwise.
     """
@@ -94,6 +94,23 @@ def check_unused_patches(patches_dir, series_path=Path('series')):
     return bool(unused_patches)
 
 
+def check_series_duplicates(patches_dir, series_path=Path('series')):
+    """
+    Checks if there are duplicate entries in the series file
+
+    series_path is a pathlib.Path to the series file relative to the patches_dir
+
+    returns True if there are duplicate entries; False otherwise.
+    """
+    entries_seen = set()
+    for entry in _read_series_file(patches_dir, series_path):
+        if entry in entries_seen:
+            get_logger().warning('Patch appears more than once in series: %s', entry)
+            return True
+        entries_seen.add(entry)
+    return False
+
+
 def main():
     """CLI entrypoint"""
 
@@ -111,6 +128,7 @@ def main():
 
     warnings = False
     warnings |= check_patch_readability(args.patches)
+    warnings |= check_series_duplicates(args.patches)
     warnings |= check_unused_patches(args.patches)
 
     if warnings:

+ 7 - 0
devutils/pytest.ini

@@ -0,0 +1,7 @@
+[pytest]
+testpaths = tests
+#filterwarnings =
+#	error
+#	ignore::DeprecationWarning
+#addopts = --cov-report term-missing --hypothesis-show-statistics -p no:warnings
+addopts = --cov=. --cov-config=.coveragerc --cov-report term-missing -p no:warnings

+ 7 - 0
devutils/run_devutils_tests.sh

@@ -0,0 +1,7 @@
+#!/bin/bash
+
+set -eux
+
+_root_dir=$(dirname $(dirname $(readlink -f $0)))
+cd ${_root_dir}/devutils
+python3 -m pytest -c ${_root_dir}/devutils/pytest.ini

+ 0 - 0
devutils/tests/__init__.py


+ 36 - 0
devutils/tests/test_check_patch_files.py

@@ -0,0 +1,36 @@
+# -*- coding: UTF-8 -*-
+
+# Copyright (c) 2019 The ungoogled-chromium Authors. All rights reserved.
+# Use of this source code is governed by a BSD-style license that can be
+# found in the LICENSE file.
+
+"""Test check_patch_files.py"""
+
+import tempfile
+from pathlib import Path
+
+from ..check_patch_files import check_series_duplicates
+
+
+def test_check_series_duplicates():
+    """Test check_series_duplicates"""
+    with tempfile.TemporaryDirectory() as tmpdirname:
+        patches_dir = Path(tmpdirname)
+        series_path = Path(tmpdirname, 'series')
+
+        # Check no duplicates
+        series_path.write_text('\n'.join([
+            'a.patch',
+            'b.patch',
+            'c.patch',
+        ]))
+        assert not check_series_duplicates(patches_dir)
+
+        # Check duplicates
+        series_path.write_text('\n'.join([
+            'a.patch',
+            'b.patch',
+            'c.patch',
+            'a.patch',
+        ]))
+        assert check_series_duplicates(patches_dir)

+ 3 - 1
devutils/validate_config.py

@@ -27,7 +27,8 @@ from pathlib import Path
 
 from check_downloads_ini import check_downloads_ini
 from check_gn_flags import check_gn_flags
-from check_patch_files import check_patch_readability, check_unused_patches
+from check_patch_files import (check_patch_readability, check_series_duplicates,
+                               check_unused_patches)
 
 
 def main():
@@ -39,6 +40,7 @@ def main():
 
     # Check patches
     warnings |= check_patch_readability(patches_dir)
+    warnings |= check_series_duplicates(patches_dir)
     warnings |= check_unused_patches(patches_dir)
 
     # Check GN flags

+ 0 - 1
utils/__init__.py

@@ -1 +0,0 @@
-# TODO: Figure out why this file is needed for Pylint to work when devutils doesn't need it