Skip to content

Commit

Permalink
Deprecate should_error, renamed to expected_error and add success_ret…
Browse files Browse the repository at this point in the history
…urncode for exitcode tests
  • Loading branch information
gerioldman committed Sep 4, 2024
1 parent d299add commit 884c54f
Show file tree
Hide file tree
Showing 13 changed files with 68 additions and 12 deletions.
7 changes: 6 additions & 1 deletion docs/markdown/Unit-tests.md
Original file line number Diff line number Diff line change
Expand Up @@ -130,7 +130,12 @@ In addition, sometimes a test fails set up so that it should fail even
if it is marked as an expected failure. The GNU standard approach in
this case is to exit the program with error code 99. Again, Meson will
detect this and report these tests as `ERROR`, ignoring the setting of
`should_fail`. This behavior was added in version 0.50.0.
`should_fail`. This behavior was added in version 0.50.0. In version
1.6.0 `should_fail` has been deprecated and renamed to `expected_fail`.

In version 1.6.0, `success_returncode` has been introduced. This makes
it possible to positively test for non-zero return codes. An example
of this would be to test if failure injection is detected in a test.

## Testing tool

Expand Down
18 changes: 18 additions & 0 deletions docs/yaml/functions/benchmark.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -40,11 +40,29 @@ kwargs:
should_fail:
type: bool
deprecated: 1.6.0
default: false
description: |
when true the test is considered passed if the
executable returns a non-zero return value (i.e. reports an error)
expected_fail:
type: bool
since: 1.6.0
default: false
description: |
when true the test is considered passed if the
executable returns a non-zero return value (i.e. reports an error)
success_returncode:
type: int
since: 1.6.0
default: 0
description: |
the test is considered passed if the
executable returns the specified returncode,
only has effect when protocol is set to exitcode
suite:
type: str | list[str]
description: |
Expand Down
5 changes: 3 additions & 2 deletions mesonbuild/backend/backends.py
Original file line number Diff line number Diff line change
Expand Up @@ -197,7 +197,8 @@ class TestSerialisation:
is_parallel: bool
cmd_args: T.List[str]
env: mesonlib.EnvironmentVariables
should_fail: bool
expected_fail: bool
success_returncode: T.Optional[int]
timeout: T.Optional[int]
workdir: T.Optional[str]
extra_paths: T.List[str]
Expand Down Expand Up @@ -1284,7 +1285,7 @@ def create_test_serialisation(self, tests: T.List['Test']) -> T.List[TestSeriali
ts = TestSerialisation(t.get_name(), t.project_name, t.suite, cmd, is_cross,
exe_wrapper, self.environment.need_exe_wrapper(),
t.is_parallel, cmd_args, t_env,
t.should_fail, t.timeout, t.workdir,
t.expected_fail, t.success_returncode, t.timeout, t.workdir,
extra_paths, t.protocol, t.priority,
isinstance(exe, (build.Target, build.CustomTargetIndex)),
isinstance(exe, build.Executable),
Expand Down
11 changes: 10 additions & 1 deletion mesonbuild/interpreter/interpreter.py
Original file line number Diff line number Diff line change
Expand Up @@ -2242,6 +2242,14 @@ def make_test(self, node: mparser.BaseNode,
if kwargs['timeout'] <= 0:
FeatureNew.single_use('test() timeout <= 0', '0.57.0', self.subproject, location=node)

expected_fail = False
if kwargs['should_fail'] is not None and kwargs['expected_fail'] is not None:
raise InvalidArguments('Tried to use both \'should_fail\' and \'expected_fail\'')
elif kwargs['should_fail'] is not None:
expected_fail = kwargs['should_fail']
elif kwargs['expected_fail'] is not None:
expected_fail = kwargs['expected_fail']

prj = self.subproject if self.is_subproject() else self.build.project_name

suite: T.List[str] = []
Expand All @@ -2258,7 +2266,8 @@ def make_test(self, node: mparser.BaseNode,
kwargs.get('is_parallel', False),
kwargs['args'],
env,
kwargs['should_fail'],
expected_fail,
kwargs['success_returncode'],
kwargs['timeout'],
kwargs['workdir'],
kwargs['protocol'],
Expand Down
5 changes: 3 additions & 2 deletions mesonbuild/interpreter/interpreterobjects.py
Original file line number Diff line number Diff line change
Expand Up @@ -755,7 +755,7 @@ def __init__(self, name: str, project: str, suite: T.List[str],
is_parallel: bool,
cmd_args: T.List[T.Union[str, mesonlib.File, build.Target, ExternalProgram]],
env: mesonlib.EnvironmentVariables,
should_fail: bool, timeout: int, workdir: T.Optional[str], protocol: str,
expected_fail: bool, success_returncode: int, timeout: int, workdir: T.Optional[str], protocol: str,
priority: int, verbose: bool):
super().__init__()
self.name = name
Expand All @@ -766,7 +766,8 @@ def __init__(self, name: str, project: str, suite: T.List[str],
self.is_parallel = is_parallel
self.cmd_args = cmd_args
self.env = env
self.should_fail = should_fail
self.expected_fail = expected_fail
self.success_returncode = success_returncode
self.timeout = timeout
self.workdir = workdir
self.protocol = TestProtocol.from_str(protocol)
Expand Down
4 changes: 3 additions & 1 deletion mesonbuild/interpreter/kwargs.py
Original file line number Diff line number Diff line change
Expand Up @@ -39,7 +39,9 @@ class BaseTest(TypedDict):
"""Shared base for the Rust module."""

args: T.List[T.Union[str, File, build.Target, ExternalProgram]]
should_fail: bool
should_fail: T.Optional[bool]
expected_fail: T.Optional[bool]
success_returncode: T.Optional[int]
timeout: int
workdir: T.Optional[str]
depends: T.List[T.Union[build.CustomTarget, build.BuildTarget]]
Expand Down
4 changes: 3 additions & 1 deletion mesonbuild/interpreter/type_checking.py
Original file line number Diff line number Diff line change
Expand Up @@ -487,7 +487,9 @@ def link_whole_validator(values: T.List[T.Union[StaticLibrary, CustomTarget, Cus
TEST_KWS: T.List[KwargInfo] = [
KwargInfo('args', ContainerTypeInfo(list, (str, File, BuildTarget, CustomTarget, CustomTargetIndex, ExternalProgram)),
listify=True, default=[]),
KwargInfo('should_fail', bool, default=False),
KwargInfo('should_fail', (bool, NoneType), deprecated='1.6.0', deprecated_message='Use expected_fail instead of should_fail'),
KwargInfo('expected_fail', (bool, NoneType), since='1.6.0'),
KwargInfo('success_returncode', (int, NoneType), since='1.6.0'),
KwargInfo('timeout', int, default=30),
KwargInfo('workdir', (str, NoneType), default=None,
validator=lambda x: 'must be an absolute path' if not os.path.isabs(x) else None),
Expand Down
9 changes: 6 additions & 3 deletions mesonbuild/mtest.py
Original file line number Diff line number Diff line change
Expand Up @@ -934,7 +934,8 @@ def __init__(self, test: TestSerialisation, test_env: T.Dict[str, str],
self.additional_error = ''
self.cmd: T.Optional[T.List[str]] = None
self.env = test_env
self.should_fail = test.should_fail
self.expected_fail = test.expected_fail
self.success_returncode = test.success_returncode
self.project = test.project_name
self.junit: T.Optional[et.ElementTree] = None
self.is_parallel = is_parallel
Expand Down Expand Up @@ -982,7 +983,7 @@ def _complete(self) -> None:
if self.res == TestResult.RUNNING:
self.res = TestResult.OK
assert isinstance(self.res, TestResult)
if self.should_fail and self.res in (TestResult.OK, TestResult.FAIL):
if self.expected_fail and self.res in (TestResult.OK, TestResult.FAIL):
self.res = TestResult.UNEXPECTEDPASS if self.res is TestResult.OK else TestResult.EXPECTEDFAIL
if self.stdo and not self.stdo.endswith('\n'):
self.stdo += '\n'
Expand Down Expand Up @@ -1038,11 +1039,13 @@ class TestRunExitCode(TestRun):
def complete(self) -> None:
if self.res != TestResult.RUNNING:
pass
elif self.returncode == self.success_returncode:
self.res = TestResult.OK
elif self.returncode == GNU_SKIP_RETURNCODE:
self.res = TestResult.SKIP
elif self.returncode == GNU_ERROR_RETURNCODE:
self.res = TestResult.ERROR
else:
elif self.success_returncode is None:
self.res = TestResult.FAIL if bool(self.returncode) else TestResult.OK
super().complete()

Expand Down
3 changes: 3 additions & 0 deletions test cases/common/278 success returncode/failing.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
int main(void) {
return 1;
}
4 changes: 4 additions & 0 deletions test cases/common/278 success returncode/meson.build
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
project('success returncode', 'c')

exe = executable('prog', 'failing.c')
test('errorcode', exe, success_returncode: 1)
3 changes: 2 additions & 1 deletion test cases/common/68 should fail/meson.build
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
project('should fail', 'c')

exe = executable('prog', 'failing.c')
test('failing', exe, should_fail : true)
test('should-failing', exe, should_fail : true)
test('expected-failing', exe, expected_fail : true)
3 changes: 3 additions & 0 deletions test cases/failing test/7 success returncode/failing.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
int main(void) {
return 0;
}
4 changes: 4 additions & 0 deletions test cases/failing test/7 success returncode/meson.build
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
project('success returncode', 'c')

exe = executable('prog', 'failing.c')
test('errorcode', exe, success_returncode: 1)

0 comments on commit 884c54f

Please sign in to comment.