interpreter: add "protocol" kwarg to test

This is the first step towards adding support for TAP.
pull/4958/head
Paolo Bonzini 6 years ago
parent f0b0bcf86d
commit 4b5cf3f7c5
  1. 11
      docs/markdown/Reference-manual.md
  2. 5
      mesonbuild/backend/backends.py
  3. 11
      mesonbuild/interpreter.py

@ -1406,10 +1406,7 @@ executable to run. The executable can be an [executable build target
object](#build-target-object) returned by object](#build-target-object) returned by
[`executable()`](#executable) or an [external program [`executable()`](#executable) or an [external program
object](#external-program-object) returned by object](#external-program-object) returned by
[`find_program()`](#find_program). The executable's exit code is used [`find_program()`](#find_program).
by the test harness to record the outcome of the test, for example
exit code zero indicates success. For more on the Meson test harness
protocol read [Unit Tests](Unit-tests.md).
Keyword arguments are the following: Keyword arguments are the following:
@ -1446,6 +1443,12 @@ Keyword arguments are the following:
before test is executed even if they have `build_by_default : false`. before test is executed even if they have `build_by_default : false`.
Since 0.46.0 Since 0.46.0
- `protocol` specifies how the test results are parsed. For now
it must be `exitcode`, that is the executable's exit code is used
by the test harness to record the outcome of the test. For example
an exit code of zero indicates success. For more on the Meson test harness
protocol read [Unit Tests](Unit-tests.md). Since 0.50.0
Defined tests can be run in a backend-agnostic way by calling Defined tests can be run in a backend-agnostic way by calling
`meson test` inside the build dir, or by using backend-specific `meson test` inside the build dir, or by using backend-specific
commands, such as `ninja test` or `msbuild RUN_TESTS.vcxproj`. commands, such as `ninja test` or `msbuild RUN_TESTS.vcxproj`.

@ -84,7 +84,7 @@ class ExecutableSerialisation:
class TestSerialisation: class TestSerialisation:
def __init__(self, name, project, suite, fname, is_cross_built, exe_wrapper, is_parallel, def __init__(self, name, project, suite, fname, is_cross_built, exe_wrapper, is_parallel,
cmd_args, env, should_fail, timeout, workdir, extra_paths): cmd_args, env, should_fail, timeout, workdir, extra_paths, protocol):
self.name = name self.name = name
self.project_name = project self.project_name = project
self.suite = suite self.suite = suite
@ -100,6 +100,7 @@ class TestSerialisation:
self.timeout = timeout self.timeout = timeout
self.workdir = workdir self.workdir = workdir
self.extra_paths = extra_paths self.extra_paths = extra_paths
self.protocol = protocol
class OptionProxy: class OptionProxy:
def __init__(self, name, value): def __init__(self, name, value):
@ -756,7 +757,7 @@ class Backend:
raise MesonException('Bad object in test command.') raise MesonException('Bad object in test command.')
ts = TestSerialisation(t.get_name(), t.project_name, t.suite, cmd, is_cross, ts = TestSerialisation(t.get_name(), t.project_name, t.suite, cmd, is_cross,
exe_wrapper, t.is_parallel, cmd_args, t.env, exe_wrapper, t.is_parallel, cmd_args, t.env,
t.should_fail, t.timeout, t.workdir, extra_paths) t.should_fail, t.timeout, t.workdir, extra_paths, t.protocol)
arr.append(ts) arr.append(ts)
return arr return arr

@ -850,7 +850,7 @@ class RunTargetHolder(InterpreterObject, ObjectHolder):
class Test(InterpreterObject): class Test(InterpreterObject):
def __init__(self, name, project, suite, exe, depends, is_parallel, def __init__(self, name, project, suite, exe, depends, is_parallel,
cmd_args, env, should_fail, timeout, workdir): cmd_args, env, should_fail, timeout, workdir, protocol):
InterpreterObject.__init__(self) InterpreterObject.__init__(self)
self.name = name self.name = name
self.suite = suite self.suite = suite
@ -863,6 +863,7 @@ class Test(InterpreterObject):
self.should_fail = should_fail self.should_fail = should_fail
self.timeout = timeout self.timeout = timeout
self.workdir = workdir self.workdir = workdir
self.protocol = protocol
def get_exe(self): def get_exe(self):
return self.exe return self.exe
@ -1973,7 +1974,8 @@ permitted_kwargs = {'add_global_arguments': {'language', 'native'},
'library': known_library_kwargs, 'library': known_library_kwargs,
'subdir': {'if_found'}, 'subdir': {'if_found'},
'subproject': {'version', 'default_options', 'required'}, 'subproject': {'version', 'default_options', 'required'},
'test': {'args', 'depends', 'env', 'is_parallel', 'should_fail', 'timeout', 'workdir', 'suite'}, 'test': {'args', 'depends', 'env', 'is_parallel', 'should_fail', 'timeout', 'workdir',
'suite', 'protocol'},
'vcs_tag': {'input', 'output', 'fallback', 'command', 'replace_string'}, 'vcs_tag': {'input', 'output', 'fallback', 'command', 'replace_string'},
} }
@ -3269,6 +3271,9 @@ This will become a hard error in the future.''' % kwargs['input'], location=self
workdir = None workdir = None
if not isinstance(timeout, int): if not isinstance(timeout, int):
raise InterpreterException('Timeout must be an integer.') raise InterpreterException('Timeout must be an integer.')
protocol = kwargs.get('protocol', 'exitcode')
if protocol not in ('exitcode',):
raise InterpreterException('Protocol must be "exitcode".')
suite = [] suite = []
prj = self.subproject if self.is_subproject() else self.build.project_name prj = self.subproject if self.is_subproject() else self.build.project_name
for s in mesonlib.stringlistify(kwargs.get('suite', '')): for s in mesonlib.stringlistify(kwargs.get('suite', '')):
@ -3280,7 +3285,7 @@ This will become a hard error in the future.''' % kwargs['input'], location=self
if not isinstance(dep, (build.CustomTarget, build.BuildTarget)): if not isinstance(dep, (build.CustomTarget, build.BuildTarget)):
raise InterpreterException('Depends items must be build targets.') raise InterpreterException('Depends items must be build targets.')
t = Test(args[0], prj, suite, exe.held_object, depends, par, cmd_args, t = Test(args[0], prj, suite, exe.held_object, depends, par, cmd_args,
env, should_fail, timeout, workdir) env, should_fail, timeout, workdir, protocol)
if is_base_test: if is_base_test:
self.build.tests.append(t) self.build.tests.append(t)
mlog.debug('Adding test', mlog.bold(args[0], True)) mlog.debug('Adding test', mlog.bold(args[0], True))

Loading…
Cancel
Save