diff options
-rw-r--r-- | docs/markdown/Reference-manual.md | 7 | ||||
-rw-r--r-- | docs/markdown/snippets/test_timeout.md | 9 | ||||
-rw-r--r-- | mesonbuild/interpreter.py | 8 | ||||
-rw-r--r-- | mesonbuild/mtest.py | 14 |
4 files changed, 28 insertions, 10 deletions
diff --git a/docs/markdown/Reference-manual.md b/docs/markdown/Reference-manual.md index cb8347a..4a1e759 100644 --- a/docs/markdown/Reference-manual.md +++ b/docs/markdown/Reference-manual.md @@ -119,7 +119,9 @@ the following: environment juggling. *(since 0.52.0)* A dictionary is also accepted. - `exe_wrapper`: a list containing the wrapper command or script followed by the arguments to it - `gdb`: if `true`, the tests are also run under `gdb` -- `timeout_multiplier`: a number to multiply the test timeout with +- `timeout_multiplier`: a number to multiply the test timeout with. + *Since 0.57* if timeout_multiplier is `<= 0` the test has infinite duration, + in previous versions of Meson the test would fail with a timeout immediately. - `is_default` *(since 0.49.0)*: a bool to set whether this is the default test setup. If `true`, the setup will be used whenever `meson test` is run without the `--setup` option. @@ -1730,7 +1732,8 @@ test(..., env: nomalloc, ...) - `timeout`: the amount of seconds the test is allowed to run, a test that exceeds its time limit is always considered failed, defaults to - 30 seconds + 30 seconds. *Since 0.57* if timeout is `<= 0` the test has infinite duration, + in previous versions of Meson the test would fail with a timeout immediately. - `workdir`: absolute path that will be used as the working directory for the test diff --git a/docs/markdown/snippets/test_timeout.md b/docs/markdown/snippets/test_timeout.md new file mode 100644 index 0000000..e436d2e --- /dev/null +++ b/docs/markdown/snippets/test_timeout.md @@ -0,0 +1,9 @@ +## `test()` timeout and timeout_multiplier value <= 0 + +`test(..., timeout: 0)`, or negative value, used to abort the test immediately +but now instead allow infinite duration. Note that omitting the `timeout` +keyword argument still defaults to 30s timeout. + +Likewise, `add_test_setup(..., timeout_multiplier: 0)`, or +`meson test --timeout-multiplier 0`, or negative value, disable tests timeout. + diff --git a/mesonbuild/interpreter.py b/mesonbuild/interpreter.py index a3fa050..f317652 100644 --- a/mesonbuild/interpreter.py +++ b/mesonbuild/interpreter.py @@ -4140,6 +4140,10 @@ This will become a hard error in the future.''' % kwargs['input'], location=self if not isinstance(should_fail, bool): raise InterpreterException('Keyword argument should_fail must be a boolean.') timeout = kwargs.get('timeout', 30) + if not isinstance(timeout, int): + raise InterpreterException('Timeout must be an integer.') + if timeout <= 0: + FeatureNew('test() timeout <= 0', '0.57.0').use(self.subproject) if 'workdir' in kwargs: workdir = kwargs['workdir'] if not isinstance(workdir, str): @@ -4148,8 +4152,6 @@ This will become a hard error in the future.''' % kwargs['input'], location=self raise InterpreterException('Workdir keyword argument must be an absolute path.') else: workdir = None - if not isinstance(timeout, int): - raise InterpreterException('Timeout must be an integer.') protocol = kwargs.get('protocol', 'exitcode') if protocol not in {'exitcode', 'tap', 'gtest', 'rust'}: raise InterpreterException('Protocol must be one of "exitcode", "tap", "gtest", or "rust".') @@ -4638,6 +4640,8 @@ different subdirectory. timeout_multiplier = kwargs.get('timeout_multiplier', 1) if not isinstance(timeout_multiplier, int): raise InterpreterException('Timeout multiplier must be a number.') + if timeout_multiplier <= 0: + FeatureNew('add_test_setup() timeout_multiplier <= 0', '0.57.0').use(self.subproject) is_default = kwargs.get('is_default', False) if not isinstance(is_default, bool): raise InterpreterException('is_default option must be a boolean') diff --git a/mesonbuild/mtest.py b/mesonbuild/mtest.py index d410dba..3525189 100644 --- a/mesonbuild/mtest.py +++ b/mesonbuild/mtest.py @@ -129,7 +129,7 @@ def add_arguments(parser: argparse.ArgumentParser) -> None: parser.add_argument('-t', '--timeout-multiplier', type=float, default=None, help='Define a multiplier for test timeout, for example ' ' when running tests in particular conditions they might take' - ' more time to execute.') + ' more time to execute. (<= 0 to disable timeout)') parser.add_argument('--setup', default=None, dest='setup', help='Which test setup to use.') parser.add_argument('--test-args', default=[], type=split_args, @@ -492,7 +492,7 @@ class ConsoleLogger(TestLogger): spaces=' ' * TestResult.maxlen(), dur=int(time.time() - self.progress_test.starttime), durlen=harness.duration_max_len, - timeout=int(self.progress_test.timeout)) + timeout=int(self.progress_test.timeout or -1)) detail = self.progress_test.detail if detail: right += ' ' + detail @@ -1158,12 +1158,14 @@ class SingleTestRunner: self.env = env self.options = options - if self.options.gdb or self.test.timeout is None: + if self.options.gdb or self.test.timeout is None or self.test.timeout <= 0: timeout = None - elif self.options.timeout_multiplier is not None: - timeout = self.test.timeout * self.options.timeout_multiplier - else: + elif self.options.timeout_multiplier is None: timeout = self.test.timeout + elif self.options.timeout_multiplier <= 0: + timeout = None + else: + timeout = self.test.timeout * self.options.timeout_multiplier self.runobj = TestRun(test, test_env, name, timeout) |