meson/run_unittests.py

163 lines
5.6 KiB
Python
Raw Normal View History

#!/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
2017-05-17 15:42:16 +08:00
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.mesonlib
import mesonbuild.coredata
import mesonbuild.modules.gnome
from mesonbuild.mesonlib import (
2021-07-25 06:31:45 +08:00
python_command
)
PkgConfigDependency: Sort -L flags according to PKG_CONFIG_PATH When there is more than one path in PKG_CONFIG_PATH. It is almost always preferred to find things in the order specified by PKG_CONFIG_PATH instead of assuming pkg-config returns flags in a meaningful order. For example: /usr/local/lib/libgtk-3.so.0 /usr/local/lib/pkgconfig/gtk+-3.0.pc /usr/local/lib/libcanberra-gtk3.so /usr/local/lib/pkgconfig/libcanberra-gtk3.pc /home/mesonuser/.local/lib/libgtk-3.so.0 /home/mesonuser/.local/lib/pkgconfig/gtk+-3.0.pc PKG_CONFIG_PATH="/home/mesonuser/.local/lib/pkgconfig:/usr/local/lib/pkgconfig" libcanberra-gtk3 is a library which depends on gtk+-3.0. The dependency is mentioned in the .pc file with 'Requires', so flags from gtk+-3.0 are used in both dynamic and static linking. Assume the user wants to compile an application which needs both libcanberra-gtk3 and gtk+-3.0. The application depends on features added in the latest version of gtk+-3.0, which can be found in the home directory of the user but not in /usr/local. When meson asks pkg-config for linker flags of libcanberra-gtk3, pkg-config picks /usr/local/lib/pkgconfig/libcanberra-gtk3.pc and /home/mesonuser/.local/lib/pkgconfig/gtk+-3.0.pc. Since these two libraries come from different prefixes, there will be two -L arguments in the output of pkg-config. If -L/usr/local/lib is put before -L/home/mesonuser/.local/lib, meson will find both libraries in /usr/local/lib instead of picking libgtk-3.so.0 from the home directory. This can result in linking failure such as undefined references error when meson decides to put linker arguments of libcanberra-gtk3 before linker arguments of gtk+-3.0. When both /usr/local/lib/libgtk-3.so.0 and /home/mesonuser/.local/lib/libgtk-3.so.0 are present on the command line, the linker chooses the first one and ignores the second one. If the application needs new symbols that are only available in the second one, the linker will throw an error because of missing symbols. To resolve the issue, we should reorder -L flags according to PKG_CONFIG_PATH ourselves before using it to find the full path of library files. This makes sure that we always follow the preferences of users, without depending on the unreliable part of pkg-config output. Fixes https://github.com/mesonbuild/meson/issues/4271.
2018-10-04 23:30:28 +08:00
import mesonbuild.dependencies.base
import mesonbuild.modules.pkgconfig
from mesonbuild.mesonmain import setup_vsenv
2019-07-08 21:19:08 +08:00
2021-07-25 06:31:45 +08:00
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
2019-07-08 21:19:08 +08:00
2017-04-23 06:11:25 +08:00
def unset_envs():
2018-04-25 08:17:55 +08:00
# For unit tests we must fully control all command lines
2017-04-23 06:11:25 +08:00
# 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())
2017-04-23 06:11:25 +08:00
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():
2017-04-23 06:11:25 +08:00
unset_envs()
setup_backend()
cases = ['InternalTests', 'DataTests', 'AllPlatformTests', 'FailureTests',
'PythonTests', 'NativeFileTests', 'RewriterTests', 'CrossFileTests',
2020-09-16 00:08:02 +08:00
'TAPParserTests', 'SubprojectsCommandTests',
'LinuxlikeTests', 'LinuxCrossArmTests', 'LinuxCrossMingwTests',
'WindowsTests', 'DarwinTests']
try:
import pytest # noqa: F401
# Need pytest-xdist for `-n` arg
import xdist # noqa: F401
pytest_args = []
# 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']
2021-06-09 17:02:38 +08:00
# 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:])
2021-06-07 19:00:59 +08:00
# 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-xdist 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))