aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--MANIFEST.in1
-rw-r--r--docs/markdown/Reference-manual.md6
-rw-r--r--docs/markdown/Unit-tests.md13
-rw-r--r--mesonbuild/backend/backends.py8
-rw-r--r--mesonbuild/envconfig.py17
-rw-r--r--mesonbuild/environment.py2
-rw-r--r--mesonbuild/interpreter.py12
-rw-r--r--mesonbuild/mintro.py1
-rwxr-xr-xrun_unittests.py2
-rw-r--r--test cases/common/224 test priorities/meson.build22
-rw-r--r--test cases/common/224 test priorities/test.sh3
11 files changed, 78 insertions, 9 deletions
diff --git a/MANIFEST.in b/MANIFEST.in
index 53853d3..13f7949 100644
--- a/MANIFEST.in
+++ b/MANIFEST.in
@@ -18,3 +18,4 @@ include run_project_tests.py
include mesonrewriter.py
include ghwt.py
include __main__.py
+include meson.py
diff --git a/docs/markdown/Reference-manual.md b/docs/markdown/Reference-manual.md
index a89d939..bdcbe1f 100644
--- a/docs/markdown/Reference-manual.md
+++ b/docs/markdown/Reference-manual.md
@@ -1520,6 +1520,12 @@ Keyword arguments are the following:
Protocol](https://www.testanything.org/)). For more on the Meson test
harness protocol read [Unit Tests](Unit-tests.md). Since 0.50.0
+- `priority` specifies the priority of a test. Tests with a
+ higher priority are *started* before tests with a lower priority.
+ The starting order of tests with identical priorities is
+ implementation-defined. The default priority is 0, negative numbers are
+ permitted. Since 0.52.0
+
Defined tests can be run in a backend-agnostic way by calling
`meson test` inside the build dir, or by using backend-specific
commands, such as `ninja test` or `msbuild RUN_TESTS.vcxproj`.
diff --git a/docs/markdown/Unit-tests.md b/docs/markdown/Unit-tests.md
index 3c27732..9c2e3d5 100644
--- a/docs/markdown/Unit-tests.md
+++ b/docs/markdown/Unit-tests.md
@@ -51,6 +51,19 @@ By default Meson uses as many concurrent processes as there are cores on the tes
$ MESON_TESTTHREADS=5 ninja test
```
+Priorities
+--
+
+Tests can be assigned a priority that determines when a test is *started*. Tests with higher priority are started first, tests with lower priority started later. The default priority is 0, meson makes no guarantee on the ordering of tests with identical priority.
+
+```meson
+test('started second', t, priority : 0)
+test('started third', t, priority : -50)
+test('started first', t, priority : 1000)
+```
+
+Note that the test priority only affects the starting order of tests and subsequent tests are affected by how long it takes previous tests to complete. It is thus possible that a higher-priority test is still running when lower-priority tests with a shorter runtime have completed.
+
## Skipped tests and hard errors
Sometimes a test can only determine at runtime that it can not be run.
diff --git a/mesonbuild/backend/backends.py b/mesonbuild/backend/backends.py
index 512eeed..c0b2666 100644
--- a/mesonbuild/backend/backends.py
+++ b/mesonbuild/backend/backends.py
@@ -86,7 +86,7 @@ class TestSerialisation:
is_parallel: bool, cmd_args: typing.List[str],
env: build.EnvironmentVariables, should_fail: bool,
timeout: typing.Optional[int], workdir: typing.Optional[str],
- extra_paths: typing.List[str], protocol: str):
+ extra_paths: typing.List[str], protocol: str, priority: int):
self.name = name
self.project_name = project
self.suite = suite
@@ -103,6 +103,7 @@ class TestSerialisation:
self.workdir = workdir
self.extra_paths = extra_paths
self.protocol = protocol
+ self.priority = priority
class OptionProxy:
def __init__(self, value):
@@ -728,7 +729,7 @@ class Backend:
def create_test_serialisation(self, tests):
arr = []
- for t in tests:
+ for t in sorted(tests, key=lambda tst: -1 * tst.priority):
exe = t.get_exe()
if isinstance(exe, dependencies.ExternalProgram):
cmd = exe.get_command()
@@ -770,7 +771,8 @@ class Backend:
raise MesonException('Bad object in test command.')
ts = TestSerialisation(t.get_name(), t.project_name, t.suite, cmd, is_cross,
exe_wrapper, t.is_parallel, cmd_args, t.env,
- t.should_fail, t.timeout, t.workdir, extra_paths, t.protocol)
+ t.should_fail, t.timeout, t.workdir,
+ extra_paths, t.protocol, t.priority)
arr.append(ts)
return arr
diff --git a/mesonbuild/envconfig.py b/mesonbuild/envconfig.py
index 5889eb1..f7a43a0 100644
--- a/mesonbuild/envconfig.py
+++ b/mesonbuild/envconfig.py
@@ -201,13 +201,13 @@ class MachineInfo:
"""
Machine is windows?
"""
- return self.system in {'windows', 'mingw'}
+ return self.system == 'windows' or 'mingw' in self.system
def is_cygwin(self) -> bool:
"""
Machine is cygwin?
"""
- return self.system == 'cygwin'
+ return self.system.startswith('cygwin')
def is_linux(self) -> bool:
"""
@@ -245,6 +245,19 @@ class MachineInfo:
"""
return self.system == 'openbsd'
+ def is_dragonflybsd(self) -> bool:
+ """Machine is DragonflyBSD?"""
+ return self.system == 'dragonfly'
+
+ def is_freebsd(self) -> bool:
+ """Machine is FreeBSD?"""
+ return self.system == 'freebsd'
+
+ def is_sunos(self) -> bool:
+ """Machine is illumos or Solaris?"""
+ return self.system == 'sunos'
+
+
# Various prefixes and suffixes for import libraries, shared libraries,
# static libraries, and executables.
# Versioning is added to these names in the backends as-needed.
diff --git a/mesonbuild/environment.py b/mesonbuild/environment.py
index 892bba7..2675bca 100644
--- a/mesonbuild/environment.py
+++ b/mesonbuild/environment.py
@@ -853,7 +853,7 @@ class Environment:
else:
m = 'Failed to detect MSVC compiler version: stderr was\n{!r}'
raise EnvironmentException(m.format(err))
- match = re.search('.*(x86|x64|ARM|ARM64).*', lookat.split('\n')[0])
+ match = re.search(' for .*(x86|x64|ARM|ARM64)$', lookat.split('\n')[0])
if match:
target = match.group(1)
else:
diff --git a/mesonbuild/interpreter.py b/mesonbuild/interpreter.py
index 5f69e22..03910b2 100644
--- a/mesonbuild/interpreter.py
+++ b/mesonbuild/interpreter.py
@@ -900,7 +900,8 @@ class Test(InterpreterObject):
def __init__(self, name: str, project: str, suite: List[str], exe: build.Executable,
depends: List[Union[build.CustomTarget, build.BuildTarget]],
is_parallel: bool, cmd_args: List[str], env: build.EnvironmentVariables,
- should_fail: bool, timeout: int, workdir: Optional[str], protocol: str):
+ should_fail: bool, timeout: int, workdir: Optional[str], protocol: str,
+ priority: int):
InterpreterObject.__init__(self)
self.name = name
self.suite = suite
@@ -914,6 +915,7 @@ class Test(InterpreterObject):
self.timeout = timeout
self.workdir = workdir
self.protocol = protocol
+ self.priority = priority
def get_exe(self):
return self.exe
@@ -2044,7 +2046,7 @@ permitted_kwargs = {'add_global_arguments': {'language', 'native'},
'subdir': {'if_found'},
'subproject': {'version', 'default_options', 'required'},
'test': {'args', 'depends', 'env', 'is_parallel', 'should_fail', 'timeout', 'workdir',
- 'suite', 'protocol'},
+ 'suite', 'protocol', 'priority'},
'vcs_tag': {'input', 'output', 'fallback', 'command', 'replace_string'},
}
@@ -3383,6 +3385,7 @@ This will become a hard error in the future.''' % kwargs['input'], location=self
self.add_test(node, args, kwargs, False)
@FeatureNewKwargs('test', '0.46.0', ['depends'])
+ @FeatureNewKwargs('test', '0.52.0', ['priority'])
@permittedKwargs(permitted_kwargs['test'])
def func_test(self, node, args, kwargs):
self.add_test(node, args, kwargs, True)
@@ -3453,8 +3456,11 @@ This will become a hard error in the future.''' % kwargs['input'], location=self
for dep in depends:
if not isinstance(dep, (build.CustomTarget, build.BuildTarget)):
raise InterpreterException('Depends items must be build targets.')
+ priority = kwargs.get('priority', 0)
+ if not isinstance(priority, int):
+ raise InterpreterException('Keyword argument priority must be an integer.')
t = Test(args[0], prj, suite, exe.held_object, depends, par, cmd_args,
- env, should_fail, timeout, workdir, protocol)
+ env, should_fail, timeout, workdir, protocol, priority)
if is_base_test:
self.build.tests.append(t)
mlog.debug('Adding test', mlog.bold(args[0], True))
diff --git a/mesonbuild/mintro.py b/mesonbuild/mintro.py
index 1d30149..49eef0a 100644
--- a/mesonbuild/mintro.py
+++ b/mesonbuild/mintro.py
@@ -321,6 +321,7 @@ def get_test_list(testdata):
to['timeout'] = t.timeout
to['suite'] = t.suite
to['is_parallel'] = t.is_parallel
+ to['priority'] = t.priority
result.append(to)
return result
diff --git a/run_unittests.py b/run_unittests.py
index c79b4e2..fb4e7cb 100755
--- a/run_unittests.py
+++ b/run_unittests.py
@@ -5476,6 +5476,8 @@ class LinuxCrossArmTests(BasePlatformTests):
@skipIfNoPkgconfig
def test_pkg_config_option(self):
+ if not shutil.which('arm-linux-gnueabihf-pkg-config'):
+ raise unittest.SkipTest('Cross-pkgconfig not found.')
testdir = os.path.join(self.unit_test_dir, '58 pkg_config_path option')
self.init(testdir, extra_args=[
'-Dbuild.pkg_config_path=' + os.path.join(testdir, 'build_extra_path'),
diff --git a/test cases/common/224 test priorities/meson.build b/test cases/common/224 test priorities/meson.build
new file mode 100644
index 0000000..b87ae65
--- /dev/null
+++ b/test cases/common/224 test priorities/meson.build
@@ -0,0 +1,22 @@
+project('test priorities', 'c')
+
+test_prog = find_program('test.sh')
+
+test('priority 0', test_prog,
+ args : ['0'],
+)
+
+test('priority neg 10', test_prog,
+ args : ['-10'],
+ priority : -10
+)
+
+test('priority 1000', test_prog,
+ args : ['1000'],
+ priority : 1000
+)
+
+test('priority 50', test_prog,
+ args : ['50'],
+ priority : 50
+)
diff --git a/test cases/common/224 test priorities/test.sh b/test cases/common/224 test priorities/test.sh
new file mode 100644
index 0000000..8506fd4
--- /dev/null
+++ b/test cases/common/224 test priorities/test.sh
@@ -0,0 +1,3 @@
+#!/bin/bash
+
+echo "$1"