#!/usr/bin/env python3 # Copyright 2016-2021 The Meson development team # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. # You may obtain a copy of the License at # http://www.apache.org/licenses/LICENSE-2.0 # Unless required by applicable law or agreed to in writing, software # distributed under the License is distributed on an "AS IS" BASIS, # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. # See the License for the specific language governing permissions and # limitations under the License. # 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.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 += ['./run_unittests.py'] 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))