diff options
Diffstat (limited to 'tools/patman')
-rw-r--r-- | tools/patman/checkpatch.py | 8 | ||||
-rw-r--r-- | tools/patman/command.py | 5 | ||||
-rw-r--r-- | tools/patman/func_test.py | 15 | ||||
-rw-r--r-- | tools/patman/get_maintainer.py | 5 | ||||
-rw-r--r-- | tools/patman/gitutil.py | 12 | ||||
-rwxr-xr-x | tools/patman/main.py (renamed from tools/patman/patman.py) | 27 | ||||
-rw-r--r-- | tools/patman/patchstream.py | 8 | ||||
l--------- | tools/patman/patman | 2 | ||||
-rw-r--r-- | tools/patman/project.py | 2 | ||||
-rw-r--r-- | tools/patman/series.py | 12 | ||||
-rw-r--r-- | tools/patman/settings.py | 13 | ||||
-rw-r--r-- | tools/patman/terminal.py | 2 | ||||
-rw-r--r-- | tools/patman/test.py | 10 | ||||
-rw-r--r-- | tools/patman/test_util.py | 125 | ||||
-rw-r--r-- | tools/patman/tools.py | 6 | ||||
-rw-r--r-- | tools/patman/tout.py | 4 |
16 files changed, 171 insertions, 85 deletions
diff --git a/tools/patman/checkpatch.py b/tools/patman/checkpatch.py index d47ea438b7d..795b5193145 100644 --- a/tools/patman/checkpatch.py +++ b/tools/patman/checkpatch.py @@ -3,12 +3,14 @@ # import collections -import command -import gitutil import os import re import sys -import terminal + +from patman import command +from patman import gitutil +from patman import terminal +from patman import tools def FindCheckPatch(): top_level = gitutil.GetTopLevel() diff --git a/tools/patman/command.py b/tools/patman/command.py index 5fbd2c4a3e9..e67ac159e5a 100644 --- a/tools/patman/command.py +++ b/tools/patman/command.py @@ -3,8 +3,9 @@ # import os -import cros_subprocess -import tools + +from patman import cros_subprocess +from patman import tools """Shell command ease-ups for Python.""" diff --git a/tools/patman/func_test.py b/tools/patman/func_test.py index 76319fff37e..b7e2825de88 100644 --- a/tools/patman/func_test.py +++ b/tools/patman/func_test.py @@ -12,15 +12,12 @@ import sys import tempfile import unittest -try: - from StringIO import StringIO -except ImportError: - from io import StringIO - -import gitutil -import patchstream -import settings -import tools +from io import StringIO + +from patman import gitutil +from patman import patchstream +from patman import settings +from patman import tools @contextlib.contextmanager diff --git a/tools/patman/get_maintainer.py b/tools/patman/get_maintainer.py index 0ffb55a8219..473f0feebf4 100644 --- a/tools/patman/get_maintainer.py +++ b/tools/patman/get_maintainer.py @@ -2,10 +2,11 @@ # Copyright (c) 2012 The Chromium OS Authors. # -import command -import gitutil import os +from patman import command +from patman import gitutil + def FindGetMaintainer(): """Look for the get_maintainer.pl script. diff --git a/tools/patman/gitutil.py b/tools/patman/gitutil.py index a2a225c6b90..770a0510142 100644 --- a/tools/patman/gitutil.py +++ b/tools/patman/gitutil.py @@ -2,17 +2,17 @@ # Copyright (c) 2011 The Chromium OS Authors. # -import command import re import os -import series import subprocess import sys -import terminal -import checkpatch -import settings -import tools +from patman import checkpatch +from patman import command +from patman import series +from patman import settings +from patman import terminal +from patman import tools # True to use --no-decorate - we check this in Setup() use_no_decorate = True diff --git a/tools/patman/patman.py b/tools/patman/main.py index 7f4ac9aef48..f3d9c0c4348 100755 --- a/tools/patman/patman.py +++ b/tools/patman/main.py @@ -12,19 +12,20 @@ import re import sys import unittest +if __name__ == "__main__": + # Allow 'from patman import xxx to work' + our_path = os.path.dirname(os.path.realpath(__file__)) + sys.path.append(os.path.join(our_path, '..')) + # Our modules -try: - from patman import checkpatch, command, gitutil, patchstream, \ - project, settings, terminal, test -except ImportError: - import checkpatch - import command - import gitutil - import patchstream - import project - import settings - import terminal - import test +from patman import checkpatch +from patman import command +from patman import gitutil +from patman import patchstream +from patman import project +from patman import settings +from patman import terminal +from patman import test parser = OptionParser() @@ -85,7 +86,7 @@ if __name__ != "__main__": # Run our meagre tests elif options.test: import doctest - import func_test + from patman import func_test sys.argv = [sys.argv[0]] result = unittest.TestResult() diff --git a/tools/patman/patchstream.py b/tools/patman/patchstream.py index df3eb7483bb..405297505c9 100644 --- a/tools/patman/patchstream.py +++ b/tools/patman/patchstream.py @@ -9,10 +9,10 @@ import re import shutil import tempfile -import command -import commit -import gitutil -from series import Series +from patman import command +from patman import commit +from patman import gitutil +from patman.series import Series # Tags that we detect and remove re_remove = re.compile('^BUG=|^TEST=|^BRANCH=|^Review URL:' diff --git a/tools/patman/patman b/tools/patman/patman index 6cc3d7a56a5..11a5d8e18ab 120000 --- a/tools/patman/patman +++ b/tools/patman/patman @@ -1 +1 @@ -patman.py
\ No newline at end of file +main.py
\ No newline at end of file diff --git a/tools/patman/project.py b/tools/patman/project.py index 1d9cfc06252..2dfc303729b 100644 --- a/tools/patman/project.py +++ b/tools/patman/project.py @@ -4,7 +4,7 @@ import os.path -import gitutil +from patman import gitutil def DetectProject(): """Autodetect the name of the current project. diff --git a/tools/patman/series.py b/tools/patman/series.py index 6d9d48b1233..e5e28cebdf5 100644 --- a/tools/patman/series.py +++ b/tools/patman/series.py @@ -2,16 +2,14 @@ # Copyright (c) 2011 The Chromium OS Authors. # -from __future__ import print_function - import itertools import os -import get_maintainer -import gitutil -import settings -import terminal -import tools +from patman import get_maintainer +from patman import gitutil +from patman import settings +from patman import terminal +from patman import tools # Series-xxx tags that we understand valid_series = ['to', 'cc', 'version', 'changes', 'prefix', 'notes', 'name', diff --git a/tools/patman/settings.py b/tools/patman/settings.py index 5dc83a85002..ca74fc611ff 100644 --- a/tools/patman/settings.py +++ b/tools/patman/settings.py @@ -2,8 +2,6 @@ # Copyright (c) 2011 The Chromium OS Authors. # -from __future__ import print_function - try: import configparser as ConfigParser except: @@ -12,9 +10,9 @@ except: import os import re -import command -import gitutil -import tools +from patman import command +from patman import gitutil +from patman import tools """Default settings per-project. @@ -36,10 +34,7 @@ class _ProjectConfigParser(ConfigParser.SafeConfigParser): - Merge general default settings/aliases with project-specific ones. # Sample config used for tests below... - >>> try: - ... from StringIO import StringIO - ... except ImportError: - ... from io import StringIO + >>> from io import StringIO >>> sample_config = ''' ... [alias] ... me: Peter P. <likesspiders@example.com> diff --git a/tools/patman/terminal.py b/tools/patman/terminal.py index 5c9e3eea20c..c709438bdc4 100644 --- a/tools/patman/terminal.py +++ b/tools/patman/terminal.py @@ -7,8 +7,6 @@ This module handles terminal interaction including ANSI color codes. """ -from __future__ import print_function - import os import re import shutil diff --git a/tools/patman/test.py b/tools/patman/test.py index 889e186606e..e7f709e34c7 100644 --- a/tools/patman/test.py +++ b/tools/patman/test.py @@ -8,11 +8,11 @@ import os import tempfile import unittest -import checkpatch -import gitutil -import patchstream -import series -import commit +from patman import checkpatch +from patman import gitutil +from patman import patchstream +from patman import series +from patman import commit class TestPatch(unittest.TestCase): diff --git a/tools/patman/test_util.py b/tools/patman/test_util.py index 09f258c26b4..4d28d9fc922 100644 --- a/tools/patman/test_util.py +++ b/tools/patman/test_util.py @@ -3,21 +3,23 @@ # Copyright (c) 2016 Google, Inc # -from __future__ import print_function - from contextlib import contextmanager import glob +import multiprocessing import os import sys +import unittest -import command +from patman import command +from patman import test_util -try: - from StringIO import StringIO -except ImportError: - from io import StringIO +from io import StringIO -PYTHON = 'python%d' % sys.version_info[0] +use_concurrent = True +try: + from concurrencytest import ConcurrentTestSuite, fork_for_tests +except: + use_concurrent = False def RunTestCoverage(prog, filter_fname, exclude_list, build_dir, required=None): @@ -46,12 +48,15 @@ def RunTestCoverage(prog, filter_fname, exclude_list, build_dir, required=None): glob_list = [] glob_list += exclude_list glob_list += ['*libfdt.py', '*site-packages*', '*dist-packages*'] - test_cmd = 'test' if 'binman.py' in prog else '-t' - cmd = ('PYTHONPATH=$PYTHONPATH:%s/sandbox_spl/tools %s-coverage run ' - '--omit "%s" %s %s -P1' % (build_dir, PYTHON, ','.join(glob_list), + test_cmd = 'test' if 'binman' in prog else '-t' + prefix = '' + if build_dir: + prefix = 'PYTHONPATH=$PYTHONPATH:%s/sandbox_spl/tools ' % build_dir + cmd = ('%spython3-coverage run ' + '--omit "%s" %s %s -P1' % (prefix, ','.join(glob_list), prog, test_cmd)) os.system(cmd) - stdout = command.Output('%s-coverage' % PYTHON, 'report') + stdout = command.Output('python3-coverage', 'report') lines = stdout.splitlines() if required: # Convert '/path/to/name.py' just the module name 'name' @@ -70,8 +75,8 @@ def RunTestCoverage(prog, filter_fname, exclude_list, build_dir, required=None): print(coverage) if coverage != '100%': print(stdout) - print("Type '%s-coverage html' to get a report in " - 'htmlcov/index.html' % PYTHON) + print("Type 'python3-coverage html' to get a report in " + 'htmlcov/index.html') print('Coverage error: %s, but should be 100%%' % coverage) ok = False if not ok: @@ -90,3 +95,95 @@ def capture_sys_output(): yield capture_out, capture_err finally: sys.stdout, sys.stderr = old_out, old_err + + +def ReportResult(toolname:str, test_name: str, result: unittest.TestResult): + """Report the results from a suite of tests + + Args: + toolname: Name of the tool that ran the tests + test_name: Name of test that was run, or None for all + result: A unittest.TestResult object containing the results + """ + # Remove errors which just indicate a missing test. Since Python v3.5 If an + # ImportError or AttributeError occurs while traversing name then a + # synthetic test that raises that error when run will be returned. These + # errors are included in the errors accumulated by result.errors. + if test_name: + errors = [] + + for test, err in result.errors: + if ("has no attribute '%s'" % test_name) not in err: + errors.append((test, err)) + result.testsRun -= 1 + result.errors = errors + + print(result) + for test, err in result.errors: + print(test.id(), err) + for test, err in result.failures: + print(err, result.failures) + if result.skipped: + print('%d binman test%s SKIPPED:' % + (len(result.skipped), 's' if len(result.skipped) > 1 else '')) + for skip_info in result.skipped: + print('%s: %s' % (skip_info[0], skip_info[1])) + if result.errors or result.failures: + print('binman tests FAILED') + return 1 + return 0 + + +def RunTestSuites(result, debug, verbosity, test_preserve_dirs, processes, + test_name, toolpath, test_class_list): + """Run a series of test suites and collect the results + + Args: + result: A unittest.TestResult object to add the results to + debug: True to enable debugging, which shows a full stack trace on error + verbosity: Verbosity level to use (0-4) + test_preserve_dirs: True to preserve the input directory used by tests + so that it can be examined afterwards (only useful for debugging + tests). If a single test is selected (in args[0]) it also preserves + the output directory for this test. Both directories are displayed + on the command line. + processes: Number of processes to use to run tests (None=same as #CPUs) + test_name: Name of test to run, or None for all + toolpath: List of paths to use for tools + test_class_list: List of test classes to run + """ + for module in []: + suite = doctest.DocTestSuite(module) + suite.run(result) + + sys.argv = [sys.argv[0]] + if debug: + sys.argv.append('-D') + if verbosity: + sys.argv.append('-v%d' % verbosity) + if toolpath: + for path in toolpath: + sys.argv += ['--toolpath', path] + + suite = unittest.TestSuite() + loader = unittest.TestLoader() + for module in test_class_list: + # Test the test module about our arguments, if it is interested + if hasattr(module, 'setup_test_args'): + setup_test_args = getattr(module, 'setup_test_args') + setup_test_args(preserve_indir=test_preserve_dirs, + preserve_outdirs=test_preserve_dirs and test_name is not None, + toolpath=toolpath, verbosity=verbosity) + if test_name: + try: + suite.addTests(loader.loadTestsFromName(test_name, module)) + except AttributeError: + continue + else: + suite.addTests(loader.loadTestsFromTestCase(module)) + if use_concurrent and processes != 1: + concurrent_suite = ConcurrentTestSuite(suite, + fork_for_tests(processes or multiprocessing.cpu_count())) + concurrent_suite.run(result) + else: + suite.run(result) diff --git a/tools/patman/tools.py b/tools/patman/tools.py index 3feddb292fc..b50370dfe8d 100644 --- a/tools/patman/tools.py +++ b/tools/patman/tools.py @@ -3,9 +3,6 @@ # Copyright (c) 2016 Google, Inc # -from __future__ import print_function - -import command import glob import os import shutil @@ -13,7 +10,8 @@ import struct import sys import tempfile -import tout +from patman import command +from patman import tout # Output directly (generally this is temporary) outdir = None diff --git a/tools/patman/tout.py b/tools/patman/tout.py index 2a384851b0d..c7e32720965 100644 --- a/tools/patman/tout.py +++ b/tools/patman/tout.py @@ -4,11 +4,9 @@ # Terminal output logging. # -from __future__ import print_function - import sys -import terminal +from patman import terminal # Output verbosity levels that we support ERROR, WARNING, NOTICE, INFO, DETAIL, DEBUG = range(6) |