diff --git a/changelog-entries/736.md b/changelog-entries/736.md new file mode 100644 index 000000000..bd4f3b08c --- /dev/null +++ b/changelog-entries/736.md @@ -0,0 +1 @@ +- Added heat-exchanger-simplified to system tests (new suite `heat_exchanger_simplified_test`). Improved Docker and Ubuntu 24.04 compatibility for local system test runs (Compose detection, precice user, build args, CalculiX download). diff --git a/heat-exchanger-simplified/reference-results/.gitkeep b/heat-exchanger-simplified/reference-results/.gitkeep new file mode 100644 index 000000000..e69de29bb diff --git a/tools/tests/components.yaml b/tools/tests/components.yaml index bd29ba88f..bcb943acd 100644 --- a/tools/tests/components.yaml +++ b/tools/tests/components.yaml @@ -117,6 +117,9 @@ calculix-adapter: TUTORIALS_REF: description: Tutorial git reference to use default: "master" + PYTHON_BINDINGS_REF: + description: Git ref of the Python bindings (required when shared Dockerfile builds python_bindings stage) + default: "master" CALCULIX_VERSION: description: Version of Calculix to use default: "2.20" diff --git a/tools/tests/dockerfiles/ubuntu_2404/Dockerfile b/tools/tests/dockerfiles/ubuntu_2404/Dockerfile index e87599880..774f13fa4 100644 --- a/tools/tests/dockerfiles/ubuntu_2404/Dockerfile +++ b/tools/tests/dockerfiles/ubuntu_2404/Dockerfile @@ -2,13 +2,15 @@ FROM ubuntu:24.04 AS base_image USER root SHELL ["/bin/bash", "-c"] ENV DEBIAN_FRONTEND=noninteractive -# We set a sensical value, but still have the possibilty to influence this via the build time arguments. +# We set a sensical value, but still have the possibilty to influence this via the build time arguments. # When the dockerfile is built using the systemtests.py we set the PRECICE_UID and PRECICE_GID to the user executing the systemtests. # This ensures no file ownership problems down the line and is the most easy fix, as we normally built the containers locally # If not built via the systemtests.py its either possible to specify manually but 1000 would be the default anyway. +# Ubuntu 24.04+ images include a default user "ubuntu" with UID/GID 1000; remove it so we can create "precice" with the same UID/GID. ARG PRECICE_UID=1000 ARG PRECICE_GID=1000 -RUN groupadd -g ${PRECICE_GID} precice && useradd -u ${PRECICE_UID} -g ${PRECICE_GID} -ms /bin/bash precice +RUN userdel ubuntu 2>/dev/null || true; groupdel ubuntu 2>/dev/null || true; \ + groupadd -g ${PRECICE_GID} precice && useradd -u ${PRECICE_UID} -g ${PRECICE_GID} -ms /bin/bash precice ENV PATH="${PATH}:/home/precice/.local/bin" ENV LD_LIBRARY_PATH="/home/precice/.local/lib:${LD_LIBRARY_PATH}" ENV CPATH="/home/precice/.local/include:$CPATH" @@ -83,7 +85,7 @@ RUN git clone https://github.com/precice/openfoam-adapter.git &&\ FROM precice_dependecies AS python_bindings COPY --from=precice /home/precice/.local/ /home/precice/.local/ -ARG PYTHON_BINDINGS_REF +ARG PYTHON_BINDINGS_REF=master USER precice WORKDIR /home/precice # Builds the precice python bindings for python3 @@ -100,7 +102,7 @@ RUN add-apt-repository -y ppa:fenics-packages/fenics && \ apt-get -qq update && \ apt-get -qq install --no-install-recommends fenics USER precice -ARG FENICS_ADAPTER_REF +ARG FENICS_ADAPTER_REF=master # Building fenics-adapter RUN python3 -m venv --system-site-packages /home/precice/venv && \ . /home/precice/venv/bin/activate && \ @@ -123,9 +125,9 @@ RUN apt-get -qq update && \ apt-get -qq install libarpack2-dev libspooles-dev libyaml-cpp-dev ARG CALCULIX_VERSION USER precice -#Download Calculix +#Download Calculix (retry for transient DNS/network) WORKDIR /home/precice -RUN wget http://www.dhondt.de/ccx_${CALCULIX_VERSION}.src.tar.bz2 && \ +RUN wget --tries=3 --retry-connrefused --timeout=30 http://www.dhondt.de/ccx_${CALCULIX_VERSION}.src.tar.bz2 && \ tar xvjf ccx_${CALCULIX_VERSION}.src.tar.bz2 && \ rm -fv ccx_${CALCULIX_VERSION}.src.tar.bz2 diff --git a/tools/tests/systemtests/Systemtest.py b/tools/tests/systemtests/Systemtest.py index 6abc5a029..165655e71 100644 --- a/tools/tests/systemtests/Systemtest.py +++ b/tools/tests/systemtests/Systemtest.py @@ -22,6 +22,36 @@ GLOBAL_TIMEOUT = 900 SHORT_TIMEOUT = 10 +# Cached result of docker compose command detection +_DOCKER_COMPOSE_CMD = None + + +def _get_docker_compose_cmd(): + """Return the docker compose command list: either ['docker', 'compose'] or ['docker-compose'].""" + global _DOCKER_COMPOSE_CMD + if _DOCKER_COMPOSE_CMD is not None: + return _DOCKER_COMPOSE_CMD + try: + subprocess.run( + ['docker', 'compose', 'version'], + capture_output=True, + timeout=5, + check=True, + ) + _DOCKER_COMPOSE_CMD = ['docker', 'compose'] + except (subprocess.CalledProcessError, FileNotFoundError, subprocess.TimeoutExpired): + try: + subprocess.run( + ['docker-compose', 'version'], + capture_output=True, + timeout=5, + check=True, + ) + _DOCKER_COMPOSE_CMD = ['docker-compose'] + except (subprocess.CalledProcessError, FileNotFoundError, subprocess.TimeoutExpired): + _DOCKER_COMPOSE_CMD = ['docker', 'compose'] # default; will fail with clear error + return _DOCKER_COMPOSE_CMD + def slugify(value, allow_unicode=False): """ @@ -381,13 +411,11 @@ def _run_field_compare(self): file.write(docker_compose_content) try: # Execute docker-compose command - process = subprocess.Popen(['docker', - 'compose', - '--file', - 'docker-compose.field_compare.yaml', - 'up', - '--exit-code-from', - 'field-compare'], + cmd = _get_docker_compose_cmd() + [ + '-f', 'docker-compose.field_compare.yaml', + 'up', '--exit-code-from', 'field-compare' + ] + process = subprocess.Popen(cmd, stdout=subprocess.PIPE, stderr=subprocess.PIPE, start_new_session=True, @@ -428,11 +456,11 @@ def _build_docker(self): try: # Execute docker-compose command - process = subprocess.Popen(['docker', - 'compose', - '--file', - 'docker-compose.tutorial.yaml', - 'build'], + cmd = _get_docker_compose_cmd() + [ + '-f', 'docker-compose.tutorial.yaml', + 'build' + ] + process = subprocess.Popen(cmd, stdout=subprocess.PIPE, stderr=subprocess.PIPE, start_new_session=True, @@ -472,11 +500,11 @@ def _run_tutorial(self): stderr_data = [] try: # Execute docker-compose command - process = subprocess.Popen(['docker', - 'compose', - '--file', - 'docker-compose.tutorial.yaml', - 'up'], + cmd = _get_docker_compose_cmd() + [ + '-f', 'docker-compose.tutorial.yaml', + 'up' + ] + process = subprocess.Popen(cmd, stdout=subprocess.PIPE, stderr=subprocess.PIPE, start_new_session=True, diff --git a/tools/tests/tests.yaml b/tools/tests/tests.yaml index cc18820ea..d4652abac 100644 --- a/tools/tests/tests.yaml +++ b/tools/tests/tests.yaml @@ -88,6 +88,14 @@ test_suites: - fluid-cpp - solid-python reference_result: ./elastic-tube-1d/reference-results/fluid-cpp_solid-python.tar.gz + heat_exchanger_simplified_test: + tutorials: + - path: heat-exchanger-simplified + case_combination: + - fluid-top-openfoam + - fluid-btm-openfoam + - solid-calculix + reference_result: ./heat-exchanger-simplified/reference-results/fluid-top-openfoam_fluid-btm-openfoam_solid-calculix.tar.gz release_test: tutorials: - path: elastic-tube-1d