Skip to content

Commit d7345a4

Browse files
systemtests: add configurable timeout per test case
1 parent ae2b3cc commit d7345a4

File tree

7 files changed

+26
-12
lines changed

7 files changed

+26
-12
lines changed

changelog-entries/735.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
- Add optional `timeout` field to `tests.yaml` entries for per-test timeout configuration. Overridable via `PRECICE_SYSTEMTEST_TIMEOUT` environment variable.

tools/tests/README.md

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -331,8 +331,11 @@ test_suites:
331331
- fluid-openfoam
332332
- solid-fenics
333333
reference_result: ./flow-over-heated-plate/reference-results/fluid-openfoam_solid-fenics.tar.gz
334+
timeout: 1200
334335
```
335336
337+
The optional `timeout` field (in seconds) sets the maximum time for the solver run and fieldcompare phases of that specific case. If omitted, it defaults to `GLOBAL_TIMEOUT` (currently 900s, overridable via the `PRECICE_SYSTEMTEST_TIMEOUT` environment variable).
338+
336339
This defines two test suites, namely `openfoam_adapter_pr` and `openfoam_adapter_release`. Each of them defines which case combinations of which tutorials to run.
337340
338341
### Generate Reference Results

tools/tests/generate_reference_results.py

Lines changed: 6 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@
22
from metadata_parser.metdata import Tutorials, ReferenceResult
33
from systemtests.TestSuite import TestSuites
44
from systemtests.SystemtestArguments import SystemtestArguments
5-
from systemtests.Systemtest import Systemtest
5+
from systemtests.Systemtest import Systemtest, GLOBAL_TIMEOUT
66
from pathlib import Path
77
from typing import List
88
from paths import PRECICE_TESTS_DIR, PRECICE_TUTORIAL_DIR
@@ -108,10 +108,12 @@ def main():
108108
for test_suite in test_suites:
109109
tutorials = test_suite.cases_of_tutorial.keys()
110110
for tutorial in tutorials:
111-
for case, reference_result in zip(
112-
test_suite.cases_of_tutorial[tutorial], test_suite.reference_results[tutorial]):
111+
timeouts = test_suite.timeouts.get(tutorial, [])
112+
for i, (case, reference_result) in enumerate(zip(
113+
test_suite.cases_of_tutorial[tutorial], test_suite.reference_results[tutorial])):
114+
timeout = timeouts[i] if i < len(timeouts) and timeouts[i] is not None else GLOBAL_TIMEOUT
113115
systemtests_to_run.add(
114-
Systemtest(tutorial, build_args, case, reference_result))
116+
Systemtest(tutorial, build_args, case, reference_result, timeout=timeout))
115117

116118
reference_result_per_tutorial = {}
117119
current_time_string = datetime.now().strftime('%Y-%m-%d %H:%M:%S')

tools/tests/systemtests.py

Lines changed: 6 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@
22
import argparse
33
from pathlib import Path
44
from systemtests.SystemtestArguments import SystemtestArguments
5-
from systemtests.Systemtest import Systemtest, display_systemtestresults_as_table
5+
from systemtests.Systemtest import Systemtest, GLOBAL_TIMEOUT, display_systemtestresults_as_table
66
from systemtests.TestSuite import TestSuites
77
from metadata_parser.metdata import Tutorials, Case
88
import logging
@@ -58,10 +58,12 @@ def main():
5858
for test_suite in test_suites_to_execute:
5959
tutorials = test_suite.cases_of_tutorial.keys()
6060
for tutorial in tutorials:
61-
for case, reference_result in zip(
62-
test_suite.cases_of_tutorial[tutorial], test_suite.reference_results[tutorial]):
61+
timeouts = test_suite.timeouts.get(tutorial, [])
62+
for i, (case, reference_result) in enumerate(zip(
63+
test_suite.cases_of_tutorial[tutorial], test_suite.reference_results[tutorial])):
64+
timeout = timeouts[i] if i < len(timeouts) and timeouts[i] is not None else GLOBAL_TIMEOUT
6365
systemtests_to_run.append(
64-
Systemtest(tutorial, build_args, case, reference_result))
66+
Systemtest(tutorial, build_args, case, reference_result, timeout=timeout))
6567

6668
if not systemtests_to_run:
6769
raise RuntimeError("Did not find any Systemtests to execute.")

tools/tests/systemtests/Systemtest.py

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -19,7 +19,7 @@
1919
import os
2020

2121

22-
GLOBAL_TIMEOUT = 900
22+
GLOBAL_TIMEOUT = int(os.environ.get("PRECICE_SYSTEMTEST_TIMEOUT", 900))
2323
SHORT_TIMEOUT = 10
2424

2525

@@ -134,6 +134,7 @@ class Systemtest:
134134
arguments: SystemtestArguments
135135
case_combination: CaseCombination
136136
reference_result: ReferenceResult
137+
timeout: int = GLOBAL_TIMEOUT
137138
params_to_use: Dict[str, str] = field(init=False)
138139
env: Dict[str, str] = field(init=False)
139140

@@ -394,7 +395,7 @@ def _run_field_compare(self):
394395
cwd=self.system_test_dir)
395396

396397
try:
397-
stdout, stderr = process.communicate(timeout=GLOBAL_TIMEOUT)
398+
stdout, stderr = process.communicate(timeout=self.timeout)
398399
except KeyboardInterrupt as k:
399400
process.kill()
400401
raise KeyboardInterrupt from k
@@ -483,7 +484,7 @@ def _run_tutorial(self):
483484
cwd=self.system_test_dir)
484485

485486
try:
486-
stdout, stderr = process.communicate(timeout=GLOBAL_TIMEOUT)
487+
stdout, stderr = process.communicate(timeout=self.timeout)
487488
except KeyboardInterrupt as k:
488489
process.kill()
489490
# process.send_signal(9)

tools/tests/systemtests/TestSuite.py

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@ class TestSuite:
1010
name: str
1111
cases_of_tutorial: Dict[Tutorial, List[CaseCombination]]
1212
reference_results: Dict[Tutorial, List[ReferenceResult]]
13+
timeouts: Dict[Tutorial, List] = field(default_factory=dict)
1314

1415
def __repr__(self) -> str:
1516
return_string = f"Test suite: {self.name} contains:"
@@ -48,6 +49,7 @@ def from_yaml(cls, path, parsed_tutorials: Tutorials):
4849
for test_suite_name in test_suites_raw:
4950
case_combinations_of_tutorial = {}
5051
reference_results_of_tutorial = {}
52+
timeouts_of_tutorial = {}
5153
# iterate over tutorials:
5254
for tutorial_case in test_suites_raw[test_suite_name]['tutorials']:
5355
tutorial = parsed_tutorials.get_by_path(tutorial_case['path'])
@@ -57,6 +59,7 @@ def from_yaml(cls, path, parsed_tutorials: Tutorials):
5759
if tutorial not in case_combinations_of_tutorial:
5860
case_combinations_of_tutorial[tutorial] = []
5961
reference_results_of_tutorial[tutorial] = []
62+
timeouts_of_tutorial[tutorial] = []
6063

6164
all_case_combinations = tutorial.case_combinations
6265
case_combination_requested = CaseCombination.from_string_list(
@@ -65,12 +68,13 @@ def from_yaml(cls, path, parsed_tutorials: Tutorials):
6568
case_combinations_of_tutorial[tutorial].append(case_combination_requested)
6669
reference_results_of_tutorial[tutorial].append(ReferenceResult(
6770
tutorial_case['reference_result'], case_combination_requested))
71+
timeouts_of_tutorial[tutorial].append(tutorial_case.get('timeout', None))
6872
else:
6973
raise Exception(
7074
f"Could not find the following cases {tutorial_case['case-combination']} in the current metadata of tutorial {tutorial.name}")
7175

7276
testsuites.append(TestSuite(test_suite_name, case_combinations_of_tutorial,
73-
reference_results_of_tutorial))
77+
reference_results_of_tutorial, timeouts_of_tutorial))
7478

7579
return cls(testsuites)
7680

tools/tests/tests.yaml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -32,6 +32,7 @@ test_suites:
3232
- fluid-openfoam
3333
- solid-nutils
3434
reference_result: ./flow-over-heated-plate/reference-results/fluid-openfoam_solid-nutils.tar.gz
35+
timeout: 1200
3536
calculix_test:
3637
tutorials:
3738
- path: perpendicular-flap

0 commit comments

Comments
 (0)