From f13224dd4a964f3c34a933249868709c96d142f5 Mon Sep 17 00:00:00 2001 From: gerioldman Date: Sun, 18 Aug 2024 15:49:17 +0200 Subject: [PATCH] Add should_error kwarg to test() --- mesonbuild/backend/backends.py | 3 ++- mesonbuild/interpreter/interpreter.py | 1 + mesonbuild/interpreter/interpreterobjects.py | 5 ++++- mesonbuild/interpreter/kwargs.py | 1 + mesonbuild/interpreter/type_checking.py | 1 + mesonbuild/mtest.py | 10 +++++++--- 6 files changed, 16 insertions(+), 5 deletions(-) diff --git a/mesonbuild/backend/backends.py b/mesonbuild/backend/backends.py index 9b26d9e6caf5..ada7fa323fef 100644 --- a/mesonbuild/backend/backends.py +++ b/mesonbuild/backend/backends.py @@ -198,6 +198,7 @@ class TestSerialisation: cmd_args: T.List[str] env: mesonlib.EnvironmentVariables should_fail: bool + should_error: bool timeout: T.Optional[int] workdir: T.Optional[str] extra_paths: T.List[str] @@ -1282,7 +1283,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.should_fail, t.should_error , t.timeout, t.workdir, extra_paths, t.protocol, t.priority, isinstance(exe, (build.Target, build.CustomTargetIndex)), isinstance(exe, build.Executable), diff --git a/mesonbuild/interpreter/interpreter.py b/mesonbuild/interpreter/interpreter.py index 9a524037af41..88a97cbbb41f 100644 --- a/mesonbuild/interpreter/interpreter.py +++ b/mesonbuild/interpreter/interpreter.py @@ -2257,6 +2257,7 @@ def make_test(self, node: mparser.BaseNode, kwargs['args'], env, kwargs['should_fail'], + kwargs['should_error'], kwargs['timeout'], kwargs['workdir'], kwargs['protocol'], diff --git a/mesonbuild/interpreter/interpreterobjects.py b/mesonbuild/interpreter/interpreterobjects.py index d5c1efaa8372..0fd1aa35588e 100644 --- a/mesonbuild/interpreter/interpreterobjects.py +++ b/mesonbuild/interpreter/interpreterobjects.py @@ -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]], env: mesonlib.EnvironmentVariables, - should_fail: bool, timeout: int, workdir: T.Optional[str], protocol: str, + should_fail: bool, should_error: bool, timeout: int, workdir: T.Optional[str], protocol: str, priority: int, verbose: bool): super().__init__() self.name = name @@ -767,6 +767,9 @@ def __init__(self, name: str, project: str, suite: T.List[str], self.cmd_args = cmd_args self.env = env self.should_fail = should_fail + self.should_error = should_error + if should_fail and should_error: + raise InterpreterException('Both should_error and should_fail cannot be true.') self.timeout = timeout self.workdir = workdir self.protocol = TestProtocol.from_str(protocol) diff --git a/mesonbuild/interpreter/kwargs.py b/mesonbuild/interpreter/kwargs.py index 461ddc9bfbe9..29b68855b45a 100644 --- a/mesonbuild/interpreter/kwargs.py +++ b/mesonbuild/interpreter/kwargs.py @@ -40,6 +40,7 @@ class BaseTest(TypedDict): args: T.List[T.Union[str, File, build.Target]] should_fail: bool + should_error: bool timeout: int workdir: T.Optional[str] depends: T.List[T.Union[build.CustomTarget, build.BuildTarget]] diff --git a/mesonbuild/interpreter/type_checking.py b/mesonbuild/interpreter/type_checking.py index 0d92a3dbf7cc..8f70403d931c 100644 --- a/mesonbuild/interpreter/type_checking.py +++ b/mesonbuild/interpreter/type_checking.py @@ -488,6 +488,7 @@ def link_whole_validator(values: T.List[T.Union[StaticLibrary, CustomTarget, Cus KwargInfo('args', ContainerTypeInfo(list, (str, File, BuildTarget, CustomTarget, CustomTargetIndex)), listify=True, default=[]), KwargInfo('should_fail', bool, default=False), + KwargInfo('should_error', bool, default=False), 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), diff --git a/mesonbuild/mtest.py b/mesonbuild/mtest.py index 9975afa22a9b..fd68ded901ad 100644 --- a/mesonbuild/mtest.py +++ b/mesonbuild/mtest.py @@ -256,6 +256,7 @@ class TestResult(enum.Enum): SKIP = 'SKIP' FAIL = 'FAIL' EXPECTEDFAIL = 'EXPECTEDFAIL' + EXPECTEDERROR = 'EXPECTEDERROR' UNEXPECTEDPASS = 'UNEXPECTEDPASS' ERROR = 'ERROR' @@ -264,7 +265,7 @@ def maxlen() -> int: return 14 # len(UNEXPECTEDPASS) def is_ok(self) -> bool: - return self in {TestResult.OK, TestResult.EXPECTEDFAIL} + return self in {TestResult.OK, TestResult.EXPECTEDFAIL, TestResult.EXPECTEDERROR} def is_bad(self) -> bool: return self in {TestResult.FAIL, TestResult.TIMEOUT, TestResult.INTERRUPT, @@ -279,7 +280,7 @@ def was_killed(self) -> bool: def colorize(self, s: str) -> mlog.AnsiDecorator: if self.is_bad(): decorator = mlog.red - elif self in (TestResult.SKIP, TestResult.EXPECTEDFAIL): + elif self in (TestResult.SKIP, TestResult.EXPECTEDFAIL, TestResult.EXPECTEDERROR): decorator = mlog.yellow elif self.is_finished(): decorator = mlog.green @@ -931,6 +932,7 @@ def __init__(self, test: TestSerialisation, test_env: T.Dict[str, str], self.cmd: T.Optional[T.List[str]] = None self.env = test_env self.should_fail = test.should_fail + self.should_error = test.should_error self.project = test.project_name self.junit: T.Optional[et.ElementTree] = None self.is_parallel = is_parallel @@ -980,6 +982,8 @@ def _complete(self) -> None: assert isinstance(self.res, TestResult) if self.should_fail and self.res in (TestResult.OK, TestResult.FAIL): self.res = TestResult.UNEXPECTEDPASS if self.res is TestResult.OK else TestResult.EXPECTEDFAIL + if self.should_error and self.res in (TestResult.OK, TestResult.ERROR): + self.res = TestResult.UNEXPECTEDPASS if self.res is TestResult.OK else TestResult.EXPECTEDERROR if self.stdo and not self.stdo.endswith('\n'): self.stdo += '\n' if self.stde and not self.stde.endswith('\n'): @@ -1737,7 +1741,7 @@ def process_test_result(self, result: TestRun) -> None: self.success_count += 1 elif result.res in {TestResult.FAIL, TestResult.ERROR, TestResult.INTERRUPT}: self.fail_count += 1 - elif result.res is TestResult.EXPECTEDFAIL: + elif result.res in {TestResult.EXPECTEDFAIL, TestResult.EXPECTEDERROR}: self.expectedfail_count += 1 elif result.res is TestResult.UNEXPECTEDPASS: self.unexpectedpass_count += 1