| #!/usr/bin/env python3 |
| # SPDX-License-Identifier: Apache-2.0 |
| # Copyright 2016-2021 The Meson development team |
| |
| # Work around some pathlib bugs... |
| from mesonbuild import _pathlib |
| import sys |
| sys.modules['pathlib'] = _pathlib |
| |
| import time |
| import subprocess |
| import os |
| import unittest |
| |
| import mesonbuild.mlog |
| import mesonbuild.depfile |
| import mesonbuild.dependencies.base |
| import mesonbuild.dependencies.factory |
| import mesonbuild.compilers |
| import mesonbuild.envconfig |
| import mesonbuild.environment |
| import mesonbuild.coredata |
| import mesonbuild.modules.gnome |
| from mesonbuild.mesonlib import python_command, setup_vsenv |
| import mesonbuild.modules.pkgconfig |
| |
| from unittests.allplatformstests import AllPlatformTests |
| from unittests.cargotests import CargoVersionTest, CargoCfgTest |
| from unittests.darwintests import DarwinTests |
| from unittests.failuretests import FailureTests |
| from unittests.linuxcrosstests import LinuxCrossArmTests, LinuxCrossMingwTests |
| from unittests.machinefiletests import NativeFileTests, CrossFileTests |
| from unittests.rewritetests import RewriterTests |
| from unittests.taptests import TAPParserTests |
| from unittests.datatests import DataTests |
| from unittests.internaltests import InternalTests |
| from unittests.linuxliketests import LinuxlikeTests |
| from unittests.pythontests import PythonTests |
| from unittests.subprojectscommandtests import SubprojectsCommandTests |
| from unittests.windowstests import WindowsTests |
| from unittests.platformagnostictests import PlatformAgnosticTests |
| |
| def unset_envs(): |
| # For unit tests we must fully control all command lines |
| # so that there are no unexpected changes coming from the |
| # environment, for example when doing a package build. |
| varnames = ['CPPFLAGS', 'LDFLAGS'] + list(mesonbuild.compilers.compilers.CFLAGS_MAPPING.values()) |
| for v in varnames: |
| if v in os.environ: |
| del os.environ[v] |
| |
| def convert_args(argv): |
| # If we got passed a list of tests, pass it on |
| pytest_args = ['-v'] if '-v' in argv else [] |
| test_list = [] |
| for arg in argv: |
| if arg.startswith('-'): |
| if arg in ('-f', '--failfast'): |
| arg = '--exitfirst' |
| pytest_args.append(arg) |
| continue |
| # ClassName.test_name => 'ClassName and test_name' |
| if '.' in arg: |
| arg = ' and '.join(arg.split('.')) |
| test_list.append(arg) |
| if test_list: |
| pytest_args += ['-k', ' or '.join(test_list)] |
| return pytest_args |
| |
| def running_single_tests(argv, cases): |
| ''' |
| Check whether we only got arguments for running individual tests, not |
| entire testcases, and not all testcases (no test args). |
| ''' |
| got_test_arg = False |
| for arg in argv: |
| if arg.startswith('-'): |
| continue |
| for case in cases: |
| if not arg.startswith(case): |
| continue |
| if '.' not in arg: |
| # Got a testcase, done |
| return False |
| got_test_arg = True |
| return got_test_arg |
| |
| def setup_backend(): |
| filtered = [] |
| be = 'ninja' |
| for a in sys.argv: |
| if a.startswith('--backend'): |
| be = a.split('=')[1] |
| else: |
| filtered.append(a) |
| # Since we invoke the tests via unittest or xtest test runner |
| # we need to pass the backend to use to the spawned process via |
| # this side channel. Yes it sucks, but at least is is fully |
| # internal to this file. |
| os.environ['MESON_UNIT_TEST_BACKEND'] = be |
| sys.argv = filtered |
| |
| def main(): |
| unset_envs() |
| setup_backend() |
| cases = ['InternalTests', 'DataTests', 'AllPlatformTests', 'FailureTests', |
| 'PythonTests', 'NativeFileTests', 'RewriterTests', 'CrossFileTests', |
| 'TAPParserTests', 'SubprojectsCommandTests', 'PlatformAgnosticTests', |
| |
| 'LinuxlikeTests', 'LinuxCrossArmTests', 'LinuxCrossMingwTests', |
| 'WindowsTests', 'DarwinTests'] |
| |
| try: |
| import pytest # noqa: F401 |
| pytest_args = [] |
| try: |
| # Need pytest-xdist for `-n` arg |
| import xdist # noqa: F401 |
| # Don't use pytest-xdist when running single unit tests since it wastes |
| # time spawning a lot of processes to distribute tests to in that case. |
| if not running_single_tests(sys.argv, cases): |
| pytest_args += ['-n', 'auto'] |
| except ImportError: |
| print('pytest-xdist not found, tests will not be distributed across CPU cores') |
| # Let there be colors! |
| if 'CI' in os.environ: |
| pytest_args += ['--color=yes'] |
| pytest_args += ['unittests'] |
| pytest_args += convert_args(sys.argv[1:]) |
| # Always disable pytest-cov because we use a custom setup |
| try: |
| import pytest_cov # noqa: F401 |
| print('Disabling pytest-cov') |
| pytest_args += ['-p' 'no:cov'] |
| except ImportError: |
| pass |
| return subprocess.run(python_command + ['-m', 'pytest'] + pytest_args).returncode |
| except ImportError: |
| print('pytest not found, using unittest instead') |
| # Fallback to plain unittest. |
| return unittest.main(defaultTest=cases, buffer=True) |
| |
| if __name__ == '__main__': |
| setup_vsenv() |
| print('Meson build system', mesonbuild.coredata.version, 'Unit Tests') |
| start = time.monotonic() |
| try: |
| raise SystemExit(main()) |
| finally: |
| print('Total time: {:.3f} seconds'.format(time.monotonic() - start)) |