xref: /openbmc/qemu/tests/qemu-iotests/297 (revision 098d983ea5ff1e2b504902d6081074f6b3bf36b8)
159aec869SMax Reitz#!/usr/bin/env python3
29dd003a9SVladimir Sementsov-Ogievskiy# group: meta
319b7868eSKevin Wolf#
419b7868eSKevin Wolf# Copyright (C) 2020 Red Hat, Inc.
519b7868eSKevin Wolf#
619b7868eSKevin Wolf# This program is free software; you can redistribute it and/or modify
719b7868eSKevin Wolf# it under the terms of the GNU General Public License as published by
819b7868eSKevin Wolf# the Free Software Foundation; either version 2 of the License, or
919b7868eSKevin Wolf# (at your option) any later version.
1019b7868eSKevin Wolf#
1119b7868eSKevin Wolf# This program is distributed in the hope that it will be useful,
1219b7868eSKevin Wolf# but WITHOUT ANY WARRANTY; without even the implied warranty of
1319b7868eSKevin Wolf# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
1419b7868eSKevin Wolf# GNU General Public License for more details.
1519b7868eSKevin Wolf#
1619b7868eSKevin Wolf# You should have received a copy of the GNU General Public License
1719b7868eSKevin Wolf# along with this program.  If not, see <http://www.gnu.org/licenses/>.
1819b7868eSKevin Wolf
1959aec869SMax Reitzimport os
2059aec869SMax Reitzimport re
2159aec869SMax Reitzimport shutil
2259aec869SMax Reitzimport subprocess
2359aec869SMax Reitzimport sys
2419b7868eSKevin Wolf
2559aec869SMax Reitzimport iotests
2619b7868eSKevin Wolf
2719b7868eSKevin Wolf
2859aec869SMax Reitz# TODO: Empty this list!
2959aec869SMax ReitzSKIP_FILES = (
3059aec869SMax Reitz    '030', '040', '041', '044', '045', '055', '056', '057', '065', '093',
31636aa64dSMax Reitz    '096', '118', '124', '132', '136', '139', '147', '148', '149',
3226db7b23SHanna Reitz    '151', '152', '155', '163', '165', '194', '196', '202',
3359aec869SMax Reitz    '203', '205', '206', '207', '208', '210', '211', '212', '213', '216',
34f08ef043SVladimir Sementsov-Ogievskiy    '218', '219', '224', '228', '234', '235', '236', '237', '238',
3559aec869SMax Reitz    '240', '242', '245', '246', '248', '255', '256', '257', '258', '260',
3659aec869SMax Reitz    '262', '264', '266', '274', '277', '280', '281', '295', '296', '298',
3759c9466dSMax Reitz    '299', '302', '303', '304', '307',
3859aec869SMax Reitz    'nbd-fault-injector.py', 'qcow2.py', 'qcow2_format.py', 'qed.py'
3959aec869SMax Reitz)
4019b7868eSKevin Wolf
4119b7868eSKevin Wolf
4259aec869SMax Reitzdef is_python_file(filename):
4359aec869SMax Reitz    if not os.path.isfile(filename):
4459aec869SMax Reitz        return False
4519b7868eSKevin Wolf
4659aec869SMax Reitz    if filename.endswith('.py'):
4759aec869SMax Reitz        return True
4859aec869SMax Reitz
4981dcb9caSHanna Reitz    with open(filename, encoding='utf-8') as f:
5059aec869SMax Reitz        try:
5159aec869SMax Reitz            first_line = f.readline()
5259aec869SMax Reitz            return re.match('^#!.*python', first_line) is not None
5359aec869SMax Reitz        except UnicodeDecodeError:  # Ignore binary files
5459aec869SMax Reitz            return False
5559aec869SMax Reitz
5659aec869SMax Reitz
5759aec869SMax Reitzdef run_linters():
58*098d983eSHanna Reitz    named_tests = [f'tests/{entry}' for entry in os.listdir('tests')]
59*098d983eSHanna Reitz    check_tests = set(os.listdir('.') + named_tests) - set(SKIP_FILES)
60*098d983eSHanna Reitz    files = [filename for filename in check_tests if is_python_file(filename)]
6159aec869SMax Reitz
6259aec869SMax Reitz    iotests.logger.debug('Files to be checked:')
6359aec869SMax Reitz    iotests.logger.debug(', '.join(sorted(files)))
6459aec869SMax Reitz
6559aec869SMax Reitz    print('=== pylint ===')
6659aec869SMax Reitz    sys.stdout.flush()
6759aec869SMax Reitz
6859aec869SMax Reitz    # Todo notes are fine, but fixme's or xxx's should probably just be
6959aec869SMax Reitz    # fixed (in tests, at least)
7059aec869SMax Reitz    env = os.environ.copy()
7159aec869SMax Reitz    qemu_module_path = os.path.join(os.path.dirname(__file__),
7259aec869SMax Reitz                                    '..', '..', 'python')
7359aec869SMax Reitz    try:
7459aec869SMax Reitz        env['PYTHONPATH'] += os.pathsep + qemu_module_path
7559aec869SMax Reitz    except KeyError:
7659aec869SMax Reitz        env['PYTHONPATH'] = qemu_module_path
7759aec869SMax Reitz    subprocess.run(('pylint-3', '--score=n', '--notes=FIXME,XXX', *files),
7859aec869SMax Reitz                   env=env, check=False)
7959aec869SMax Reitz
8059aec869SMax Reitz    print('=== mypy ===')
8159aec869SMax Reitz    sys.stdout.flush()
8259aec869SMax Reitz
8359aec869SMax Reitz    # We have to call mypy separately for each file.  Otherwise, it
8459aec869SMax Reitz    # will interpret all given files as belonging together (i.e., they
8559aec869SMax Reitz    # may not both define the same classes, etc.; most notably, they
8659aec869SMax Reitz    # must not both define the __main__ module).
8759aec869SMax Reitz    env['MYPYPATH'] = env['PYTHONPATH']
8859aec869SMax Reitz    for filename in files:
8959aec869SMax Reitz        p = subprocess.run(('mypy',
9059aec869SMax Reitz                            '--warn-unused-configs',
9159aec869SMax Reitz                            '--disallow-subclassing-any',
9259aec869SMax Reitz                            '--disallow-any-generics',
9359aec869SMax Reitz                            '--disallow-incomplete-defs',
9459aec869SMax Reitz                            '--disallow-untyped-decorators',
9559aec869SMax Reitz                            '--no-implicit-optional',
9659aec869SMax Reitz                            '--warn-redundant-casts',
9759aec869SMax Reitz                            '--warn-unused-ignores',
9859aec869SMax Reitz                            '--no-implicit-reexport',
997f0a143bSJohn Snow                            '--namespace-packages',
10059aec869SMax Reitz                            filename),
10159aec869SMax Reitz                           env=env,
10259aec869SMax Reitz                           check=False,
10359aec869SMax Reitz                           stdout=subprocess.PIPE,
10459aec869SMax Reitz                           stderr=subprocess.STDOUT,
10559aec869SMax Reitz                           universal_newlines=True)
10659aec869SMax Reitz
10759aec869SMax Reitz        if p.returncode != 0:
10859aec869SMax Reitz            print(p.stdout)
10959aec869SMax Reitz
11059aec869SMax Reitz
11159aec869SMax Reitzfor linter in ('pylint-3', 'mypy'):
11259aec869SMax Reitz    if shutil.which(linter) is None:
11359aec869SMax Reitz        iotests.notrun(f'{linter} not found')
11459aec869SMax Reitz
11559aec869SMax Reitziotests.script_main(run_linters)
116