Skip to content

Commit c1f0df0

Browse files
committed
Add timeout parameter
1 parent c87b796 commit c1f0df0

File tree

4 files changed

+41
-3
lines changed

4 files changed

+41
-3
lines changed

README.md

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -82,9 +82,10 @@ Custom options for test_partdiff:
8282
(default: $PWD).
8383
--shuffle=[SEED] Shuffle the test cases.
8484
--allow-extra-iterations=n
85-
For term=prec, allow more iterations than the (serial)
85+
For term=acc, allow more iterations than the (serial)
8686
reference implementation would do (0 == disallow; n ==
8787
allow n more; -1 == unlimited)
88+
--timeout=n Stop EXECUTABLE after n seconds (can be float).
8889
```
8990

9091
The custom options are explained below.
@@ -225,3 +226,7 @@ Allowed values for this parameter are:
225226
226227
> [!IMPORTANT]
227228
> Since `partdiff_tester` probably needs to execute the reference implementation in the described scenario, it is best to always pass `--reference-source=auto` alongside this parameter. Otherwise, the tests will likely fail.
229+
230+
### `timeout`
231+
232+
A timeout in seconds for `EXECUTABLE`. Zero means no timeout.

conftest.py

Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -234,6 +234,27 @@ def shuffle_type(value: str) -> tuple[ShuffleType, int | None]:
234234
return (ShuffleType.SHUFFLE_EXPL_SEED, int(value))
235235

236236

237+
def timeout(value: str) -> float | None:
238+
"""Parse a timeout value from a str.
239+
240+
Args:
241+
value (str): The value to parse.
242+
243+
Raises:
244+
ValueError: When the value cannot be parsed or is not a non-negative
245+
float.
246+
247+
Returns:
248+
float | None: The parsed timeout, or None if 0 was passed.
249+
"""
250+
parsed_value = float(value)
251+
if parsed_value < 0:
252+
raise ValueError("Timeout must be positive.")
253+
if parsed_value == 0.0:
254+
return None
255+
return parsed_value
256+
257+
237258
def pytest_addoption(parser: pytest.Parser) -> None:
238259
"""
239260
See https://docs.pytest.org/en/7.1.x/reference/reference.html#pytest.hookspec.pytest_addoption
@@ -329,6 +350,13 @@ def pytest_addoption(parser: pytest.Parser) -> None:
329350
type=extra_iterations,
330351
default=0,
331352
)
353+
custom_options.addoption(
354+
"--timeout",
355+
help="Stop EXECUTABLE after n seconds (can be float). Zero means no timeout.",
356+
metavar="n",
357+
type=timeout,
358+
default=None,
359+
)
332360

333361

334362
@pytest.fixture

test_partdiff.py

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -62,9 +62,10 @@ def test_partdiff_parametrized(
6262
reference_source = pytestconfig.getoption("reference_source")
6363
cwd = pytestconfig.getoption("cwd")
6464
allow_extra_iterations = pytestconfig.getoption("allow_extra_iterations")
65+
timeout = pytestconfig.getoption("timeout")
6566

6667
actual_output = util.get_actual_output(
67-
partdiff_params, partdiff_executable, use_valgrind, cwd
68+
partdiff_params, partdiff_executable, use_valgrind, cwd, timeout
6869
)
6970
reference_output = util.get_reference_output(
7071
partdiff_params, reference_output_data, reference_source

util.py

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -230,6 +230,7 @@ def get_actual_output(
230230
partdiff_executable: list[str],
231231
use_valgrind: bool,
232232
cwd: Path | None,
233+
timeout: float | None,
233234
) -> str:
234235
"""Get the actual output for a parameter combination.
235236
@@ -238,14 +239,17 @@ def get_actual_output(
238239
partdiff_executable (list[str]): The executable to run.
239240
use_valgrind (bool): Wether valgrind shall be used.
240241
cwd (Path | None): The working directory of the executable.
242+
timeout (float | None): The timeout in seconds, or None for no timeout.
241243
242244
Returns:
243245
str: The output of the executable.
244246
"""
245247
command_line = partdiff_executable + list(partdiff_params)
246248
if use_valgrind:
247249
command_line = ["valgrind", "--leak-check=full"] + command_line
248-
return subprocess.check_output(command_line, cwd=cwd).decode("utf-8")
250+
return subprocess.check_output(command_line, cwd=cwd, timeout=timeout).decode(
251+
"utf-8"
252+
)
249253

250254

251255
def check_executable_exists(executable: list[str], cwd: Path | None) -> None:

0 commit comments

Comments
 (0)