diff options
-rw-r--r-- | docs/markdown/Reference-manual.md | 7 | ||||
-rw-r--r-- | docs/markdown/snippets/exe_wrapper_for_cross_built_tests.md | 9 | ||||
-rw-r--r-- | mesonbuild/mtest.py | 32 | ||||
-rwxr-xr-x | run_unittests.py | 12 | ||||
-rwxr-xr-x | test cases/unit/72 cross test passed/exewrapper.py | 24 | ||||
-rw-r--r-- | test cases/unit/72 cross test passed/meson.build | 7 | ||||
-rw-r--r-- | test cases/unit/72 cross test passed/meson_options.txt | 5 |
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, +) |