aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--docs/markdown/Reference-manual.md7
-rw-r--r--docs/markdown/snippets/exe_wrapper_for_cross_built_tests.md9
-rw-r--r--mesonbuild/mtest.py32
-rwxr-xr-xrun_unittests.py12
-rwxr-xr-xtest cases/unit/72 cross test passed/exewrapper.py24
-rw-r--r--test cases/unit/72 cross test passed/meson.build7
-rw-r--r--test cases/unit/72 cross test passed/meson_options.txt5
7 files changed, 75 insertions, 21 deletions
diff --git a/docs/markdown/Reference-manual.md b/docs/markdown/Reference-manual.md
index 1bd5ff0..9b5d657 100644
--- a/docs/markdown/Reference-manual.md
+++ b/docs/markdown/Reference-manual.md
@@ -1613,6 +1613,13 @@ object](#build-target-object) returned by
object](#external-program-object) returned by
[`find_program()`](#find_program).
+*Since 0.55.0* When cross compiling, if an exe_wrapper is needed and defined
+the environment variable `MESON_EXE_WRAPPER` will be set to the string value
+of that wrapper (implementation detail: using `mesonlib.join_args`). Test
+scripts may use this to run cross built binaries. If your test needs
+`MESON_EXE_WRAPPER` in cross build situations it is your responsibility to
+return code 77 to tell the harness to report "skip"
+
By default, environment variable
[`MALLOC_PERTURB_`](http://man7.org/linux/man-pages/man3/mallopt.3.html)
is automatically set by `meson test` to a random value between 1..255.
diff --git a/docs/markdown/snippets/exe_wrapper_for_cross_built_tests.md b/docs/markdown/snippets/exe_wrapper_for_cross_built_tests.md
new file mode 100644
index 0000000..ebdd8a7
--- /dev/null
+++ b/docs/markdown/snippets/exe_wrapper_for_cross_built_tests.md
@@ -0,0 +1,9 @@
+## Test scripts are given the exe wrapper if needed
+
+Meson will now set the `MESON_EXE_WRAPPER` as the properly wrapped and joined
+representation. For Unix-like OSes this means python's shelx.join, on Windows
+an implementation that attempts to properly quote windows argument is used.
+This allow wrapper scripts to run test binaries, instead of just skipping.
+
+for example, if the wrapper is `['emulator', '--script']`, it will be passed
+as `MESON_EXE_WRAPPER="emulator --script"`.
diff --git a/mesonbuild/mtest.py b/mesonbuild/mtest.py
index 8806932..4aafe62 100644
--- a/mesonbuild/mtest.py
+++ b/mesonbuild/mtest.py
@@ -42,7 +42,7 @@ from . import build
from . import environment
from . import mlog
from .dependencies import ExternalProgram
-from .mesonlib import MesonException, get_wine_shortpath, split_args
+from .mesonlib import MesonException, get_wine_shortpath, split_args, join_args
from .backend.backends import TestProtocol
if T.TYPE_CHECKING:
@@ -609,20 +609,19 @@ class SingleTestRunner:
return ['java', '-jar'] + self.test.fname
elif not self.test.is_cross_built and run_with_mono(self.test.fname[0]):
return ['mono'] + self.test.fname
- else:
- if self.test.is_cross_built and self.test.needs_exe_wrapper:
- if self.test.exe_runner is None:
- # Can not run test on cross compiled executable
- # because there is no execute wrapper.
- return None
- elif self.test.cmd_is_built:
- # If the command is not built (ie, its a python script),
- # then we don't check for the exe-wrapper
- if not self.test.exe_runner.found():
- msg = 'The exe_wrapper defined in the cross file {!r} was not ' \
- 'found. Please check the command and/or add it to PATH.'
- raise TestException(msg.format(self.test.exe_runner.name))
- return self.test.exe_runner.get_command() + self.test.fname
+ elif self.test.cmd_is_built and self.test.needs_exe_wrapper:
+ if self.test.exe_runner is None:
+ # Can not run test on cross compiled executable
+ # because there is no execute wrapper.
+ return None
+ elif self.test.cmd_is_built:
+ # If the command is not built (ie, its a python script),
+ # then we don't check for the exe-wrapper
+ if not self.test.exe_runner.found():
+ msg = ('The exe_wrapper defined in the cross file {!r} was not '
+ 'found. Please check the command and/or add it to PATH.')
+ raise TestException(msg.format(self.test.exe_runner.name))
+ return self.test.exe_runner.get_command() + self.test.fname
return self.test.fname
def run(self) -> TestRun:
@@ -868,6 +867,9 @@ class TestHarness:
env = os.environ.copy()
test_env = test.env.get_env(env)
env.update(test_env)
+ if (test.is_cross_built and test.needs_exe_wrapper and
+ test.exe_runner and test.exe_runner.found()):
+ env['MESON_EXE_WRAPPER'] = join_args(test.exe_runner.get_command())
return SingleTestRunner(test, test_env, env, options)
def process_test_result(self, result: TestRun) -> None:
diff --git a/run_unittests.py b/run_unittests.py
index e326aa4..3e25f94 100755
--- a/run_unittests.py
+++ b/run_unittests.py
@@ -7584,7 +7584,7 @@ class CrossFileTests(BasePlatformTests):
''')
def test_needs_exe_wrapper_true(self):
- testdir = os.path.join(self.common_test_dir, '1 trivial')
+ testdir = os.path.join(self.unit_test_dir, '72 cross test passed')
with tempfile.TemporaryDirectory() as d:
p = Path(d) / 'crossfile'
with p.open('wt') as f:
@@ -7594,7 +7594,7 @@ class CrossFileTests(BasePlatformTests):
self.assertRegex(out, r'Skipped:\s*1\s*\n')
def test_needs_exe_wrapper_false(self):
- testdir = os.path.join(self.common_test_dir, '1 trivial')
+ testdir = os.path.join(self.unit_test_dir, '72 cross test passed')
with tempfile.TemporaryDirectory() as d:
p = Path(d) / 'crossfile'
with p.open('wt') as f:
@@ -7604,7 +7604,7 @@ class CrossFileTests(BasePlatformTests):
self.assertNotRegex(out, r'Skipped:\s*1\n')
def test_needs_exe_wrapper_true_wrapper(self):
- testdir = os.path.join(self.common_test_dir, '1 trivial')
+ testdir = os.path.join(self.unit_test_dir, '72 cross test passed')
with tempfile.TemporaryDirectory() as d:
s = Path(d) / 'wrapper.py'
with s.open('wt') as f:
@@ -7616,9 +7616,9 @@ class CrossFileTests(BasePlatformTests):
needs_exe_wrapper=True,
exe_wrapper=[str(s)]))
- self.init(testdir, extra_args=['--cross-file=' + str(p)])
+ self.init(testdir, extra_args=['--cross-file=' + str(p), '-Dexpect=true'])
out = self.run_target('test')
- self.assertNotRegex(out, r'Skipped:\s*1\s*\n')
+ self.assertRegex(out, r'Ok:\s*3\s*\n')
def test_cross_exe_passed_no_wrapper(self):
testdir = os.path.join(self.unit_test_dir, '72 cross test passed')
@@ -7630,7 +7630,7 @@ class CrossFileTests(BasePlatformTests):
self.init(testdir, extra_args=['--cross-file=' + str(p)])
self.build()
out = self.run_target('test')
- self.assertRegex(out, r'Skipped:\s*2\s*\n')
+ self.assertRegex(out, r'Skipped:\s*1\s*\n')
# The test uses mocking and thus requires that the current process is the
# one to run the Meson steps. If we are using an external test executable
diff --git a/test cases/unit/72 cross test passed/exewrapper.py b/test cases/unit/72 cross test passed/exewrapper.py
new file mode 100755
index 0000000..2c15ed6
--- /dev/null
+++ b/test cases/unit/72 cross test passed/exewrapper.py
@@ -0,0 +1,24 @@
+#!/usr/bin/env python3
+# Test that the MESON_EXE_WRAPPER environment variable is set
+
+import argparse
+import os
+import sys
+
+
+def main():
+ parser = argparse.ArgumentParser()
+ parser.add_argument('binary') # unused, but needed for test behavior
+ parser.add_argument('--expected', action='store_true')
+ args = parser.parse_args()
+
+ defined = 'MESON_EXE_WRAPPER' in os.environ
+
+ if args.expected != defined:
+ print(os.environ, file=sys.stderr)
+ return 1
+ return 0
+
+
+if __name__ == "__main__":
+ sys.exit(main())
diff --git a/test cases/unit/72 cross test passed/meson.build b/test cases/unit/72 cross test passed/meson.build
index cb3bb6d..4deb74b 100644
--- a/test cases/unit/72 cross test passed/meson.build
+++ b/test cases/unit/72 cross test passed/meson.build
@@ -10,3 +10,10 @@ py = import('python').find_installation()
test('root', e)
test('main', py, args : [meson.current_source_dir() / 'script.py', e])
+
+wrapper_args = []
+if get_option('expect')
+ wrapper_args += '--expected'
+endif
+
+test('exe_wrapper in env', py, args : [meson.current_source_dir() / 'exewrapper.py', e, wrapper_args])
diff --git a/test cases/unit/72 cross test passed/meson_options.txt b/test cases/unit/72 cross test passed/meson_options.txt
new file mode 100644
index 0000000..084c776
--- /dev/null
+++ b/test cases/unit/72 cross test passed/meson_options.txt
@@ -0,0 +1,5 @@
+option(
+ 'expect',
+ type : 'boolean',
+ value : false,
+)