Skip to content

Commit 7ae8b8a

Browse files
Parallelize PR system tests via GitHub Actions matrix.
Add release_test_shard_1/2 covering the same cases as release_test, and run them as separate matrix jobs for clearer logs and cheaper reruns.
1 parent 5fe1c1f commit 7ae8b8a

4 files changed

Lines changed: 122 additions & 2 deletions

File tree

.github/workflows/system-tests-pr.yml

Lines changed: 10 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -145,12 +145,20 @@ jobs:
145145
} >> "$GITHUB_STEP_SUMMARY"
146146
147147
run-system-tests:
148-
name: Trigger system tests
148+
name: Trigger system tests (shard ${{ matrix.shard }})
149149
if: ${{ github.event.label.name == 'trigger-system-tests' }}
150150
needs: gather-refs
151+
strategy:
152+
fail-fast: false
153+
matrix:
154+
include:
155+
- shard: 1
156+
suites: release_test_shard_1
157+
- shard: 2
158+
suites: release_test_shard_2
151159
uses: precice/tutorials/.github/workflows/run_testsuite_workflow.yml@develop
152160
with:
153-
suites: release_test
161+
suites: ${{ matrix.suites }}
154162
build_args: "PLATFORM:ubuntu_2404,\
155163
PRECICE_REF:${{ needs.gather-refs.outputs.ref-precice }},\
156164
PYTHON_BINDINGS_REF:${{ needs.gather-refs.outputs.ref-python-bindings }},\

tools/tests/README.md

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -54,6 +54,12 @@ To be able to fill in the right case tuple into the `tests.yaml`, you can use th
5454

5555
## Running the system tests on GitHub Actions
5656

57+
Pull-request system tests run as a GitHub Actions matrix over `release_test_shard_1` and
58+
`release_test_shard_2` (together they cover the same cases as `release_test`). When a shard
59+
fails, re-run only the failed matrix job. With multiple `precice-tests-vm` runners, shards
60+
may execute concurrently; overlapping Docker image builds are possible and acceptable unless
61+
CI reports failures.
62+
5763
Go to Actions > [Run Testsuite (manual)](https://github.com/precice/tutorials/actions/workflows/run_testsuite_manual.yml) to see this workflow.
5864

5965
After bringing these changes to `master`, the manual triggering option should be visible on the top right. Until that happens, we can only trigger this workflow manually from the [GitHub CLI](https://github.blog/changelog/2021-04-15-github-cli-1-9-enables-you-to-work-with-github-actions-from-your-terminal/):

tools/tests/tests.yaml

Lines changed: 55 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -551,6 +551,61 @@ test_suites:
551551
- *water-hammer_fluid1d-left-nutils_fluid3d-right-openfoam
552552
- *wolf-sheep-soil-creep_soil-creep-landlab_wolf-sheep-grass-mesa
553553

554+
# Shards of release_test for parallel CI (union = release_test, no duplicates).
555+
release_test_shard_1:
556+
tutorials:
557+
- *breaking-dam-2d_fluid-openfoam_solid-calculix
558+
- *channel-transport_fluid-openfoam_transport-nutils
559+
- *channel-transport-reaction_fluid-fenics_chemical-fenics
560+
- *elastic-tube-1d_fluid-cpp_solid-cpp
561+
- *elastic-tube-1d_fluid-cpp_solid-python
562+
- *elastic-tube-1d_fluid-fortran_solid-fortran
563+
- *elastic-tube-1d_fluid-fortran-module_solid-fortran-module
564+
- *elastic-tube-1d_fluid-python_solid-python
565+
- *elastic-tube-3d_fluid-openfoam_solid-calculix
566+
- *flow-around-controlled-moving-cylinder_controller-fmi_fluid-openfoam_solid-python
567+
- *flow-over-heated-plate_fluid-openfoam_solid-fenics
568+
- *flow-over-heated-plate_fluid-openfoam_solid-nutils
569+
- *flow-over-heated-plate_fluid-openfoam_solid-openfoam
570+
- *flow-over-heated-plate_fluid-su2_solid-openfoam
571+
- *flow-over-heated-plate-nearest-projection_fluid-openfoam_solid-openfoam
572+
- *flow-over-heated-plate-partitioned-flow_fluid1-openfoam_fluid2-openfoam_solid-openfoam
573+
- *flow-over-heated-plate-two-meshes_fluid-openfoam_solid-calculix
574+
- *free-flow-over-porous-media_free-flow-dumux_porous-media-dumux
575+
- *heat-exchanger_fluid-inner-openfoam_solid-calculix_fluid-outer-openfoam
576+
- *heat-exchanger-simplified_fluid-top-openfoam_fluid-bottom-openfoam_solid-calculix
577+
- *multiple-perpendicular-flaps_fluid-openfoam_solid-upstream-dealii_solid-downstream-dealii
578+
- *oscillator_mass-left-fmi_mass-right-fmi
579+
- *oscillator_mass-left-python_mass-right-python
580+
- *oscillator-overlap_mass-left-python_mass-right-python
581+
582+
release_test_shard_2:
583+
tutorials:
584+
- *partitioned-backwards-facing-step_fluid1-openfoam_fluid2-openfoam
585+
- *partitioned-elastic-beam_dirichlet-calculix_neumann-calculix
586+
- *partitioned-heat-conduction_dirichlet-fenics_neumann-fenics
587+
- *partitioned-heat-conduction_dirichlet-openfoam_neumann-openfoam
588+
- *partitioned-heat-conduction-complex_dirichlet-fenics_neumann-fenics
589+
- *partitioned-heat-conduction-direct_dirichlet-nutils_neumann-nutils
590+
- *partitioned-heat-conduction-overlap_left-fenics_right-fenics
591+
- *partitioned-pipe_fluid1-openfoam-pimplefoam_fluid2-openfoam-pimplefoam
592+
- *partitioned-pipe_fluid1-openfoam-sonicliquidfoam_fluid2-openfoam-sonicliquidfoam
593+
- *partitioned-pipe-multiscale_fluid1d-left-nutils_fluid3d-right-openfoam
594+
- *partitioned-pipe-two-phase_fluid1-openfoam_fluid2-openfoam
595+
- *perpendicular-flap_fluid-fake_solid-fake
596+
- *perpendicular-flap_fluid-openfoam_solid-calculix
597+
- *perpendicular-flap_fluid-openfoam_solid-dealii
598+
- *perpendicular-flap_fluid-openfoam_solid-fenics
599+
- *perpendicular-flap_fluid-openfoam_solid-openfoam
600+
- *perpendicular-flap_fluid-su2_solid-fenics
601+
- *quickstart_openfoam_cpp
602+
- *resonant-circuit_capacitor-python_coil-python
603+
- *turek-hron-fsi3_fluid-openfoam_solid-dealii
604+
- *volume-coupled-diffusion_source-fenics_drain-fenics
605+
- *volume-coupled-flow_fluid-openfoam_source-nutils
606+
- *water-hammer_fluid1d-left-nutils_fluid3d-right-openfoam
607+
- *wolf-sheep-soil-creep_soil-creep-landlab_wolf-sheep-grass-mesa
608+
554609
# These test suites take longer to run. They are available, but not regularly executed.
555610
extra:
556611
tutorials:
Lines changed: 51 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,51 @@
1+
#!/usr/bin/env python3
2+
"""Verify release_test_shard_1/2 partition release_test without gaps or duplicates."""
3+
4+
from metadata_parser.metdata import Tutorials
5+
from systemtests.Systemtest import Systemtest
6+
from systemtests.SystemtestArguments import SystemtestArguments
7+
from systemtests.TestSuite import TestSuites
8+
from paths import PRECICE_TESTS_DIR, PRECICE_TUTORIAL_DIR
9+
10+
11+
def _cases_for_suite(suite_name: str) -> list[str]:
12+
tutorials = Tutorials.from_path(PRECICE_TUTORIAL_DIR)
13+
suites = TestSuites.from_yaml(PRECICE_TESTS_DIR / "tests.yaml", tutorials)
14+
suite = suites.get_by_name(suite_name)
15+
if suite is None:
16+
raise SystemExit(f"Unknown test suite: {suite_name}")
17+
18+
build_args = SystemtestArguments.from_args(None)
19+
cases: list[str] = []
20+
for tutorial in suite.cases_of_tutorial:
21+
for case, reference_result in zip(
22+
suite.cases_of_tutorial[tutorial],
23+
suite.reference_results[tutorial]):
24+
systemtest = Systemtest(tutorial, build_args, case, reference_result)
25+
cases.append(str(systemtest))
26+
return sorted(cases)
27+
28+
29+
def main() -> None:
30+
release = _cases_for_suite("release_test")
31+
shard_1 = _cases_for_suite("release_test_shard_1")
32+
shard_2 = _cases_for_suite("release_test_shard_2")
33+
combined = sorted(shard_1 + shard_2)
34+
35+
if release != combined:
36+
only_release = set(release) - set(combined)
37+
only_shards = set(combined) - set(release)
38+
duplicates = len(shard_1) + len(shard_2) - len(set(shard_1 + shard_2))
39+
raise SystemExit(
40+
f"Shard mismatch: release_test={len(release)}, "
41+
f"shard_1={len(shard_1)}, shard_2={len(shard_2)}, "
42+
f"duplicates={duplicates}, only_in_release={len(only_release)}, "
43+
f"only_in_shards={len(only_shards)}")
44+
45+
print(
46+
f"OK: release_test ({len(release)} cases) = "
47+
f"shard_1 ({len(shard_1)}) + shard_2 ({len(shard_2)})")
48+
49+
50+
if __name__ == "__main__":
51+
main()

0 commit comments

Comments
 (0)