Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
131 changes: 131 additions & 0 deletions .github/workflows/dt4acc-integration.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,131 @@
name: dt4acc integration

on:
workflow_dispatch:
inputs:
dt4acc_image_uri:
description: "Apptainer ORAS image URI for the dt4acc twin"
required: false
default: "oras://gitlab-registry.synchrotron-soleil.fr/software-control-system/digitaltwin/dt4acc/dt4acc-soleil-twin/dt4acc-soleil-twin:latest"
pull_request:
branches: ["main"]
paths:
- ".github/workflows/dt4acc-integration.yml"
- "pyaml/**"
- "tests/integration/**"
- "pyproject.toml"

permissions:
contents: read

jobs:
smoke:
runs-on: ubuntu-latest
timeout-minutes: 30

defaults:
run:
shell: bash -el {0}

env:
TANGO_HOST: 127.0.0.1:10000
DT4ACC_IMAGE_URI: ${{ inputs.dt4acc_image_uri || 'oras://gitlab-registry.synchrotron-soleil.fr/software-control-system/digitaltwin/dt4acc/dt4acc-soleil-twin/dt4acc-soleil-twin:latest' }}
DT4ACC_REGISTRY_USER: ${{ secrets.DT4ACC_REGISTRY_USER }}
DT4ACC_REGISTRY_PASSWORD: ${{ secrets.DT4ACC_REGISTRY_PASSWORD }}

steps:
- uses: actions/checkout@v4

- name: Set up Apptainer
uses: eWaterCycle/setup-apptainer@v2

- name: Set up Python environment
uses: mamba-org/setup-micromamba@v2
with:
environment-name: pyaml-dt4acc-integration
create-args: >-
-c conda-forge
python=3.12
pip
pytest
pytango
cache-environment: true

- name: Install pyAML and control-system backends
run: |
python -m pip install --upgrade pip
python -m pip install -e ".[test]"
python -m pip install "ophyd-async[tango]"
python -m pip install --no-deps \
"tango-pyaml @ git+https://github.com/python-accelerator-middle-layer/tango-pyaml.git" \
"pyaml-cs-oa @ git+https://github.com/python-accelerator-middle-layer/pyaml-cs-oa.git"
python -c "import tango; import tango.pyaml; import pyaml_cs_oa"

- name: Log in to GitLab registry
if: ${{ env.DT4ACC_REGISTRY_USER != '' && env.DT4ACC_REGISTRY_PASSWORD != '' }}
run: |
printf '%s' "${DT4ACC_REGISTRY_PASSWORD}" |
apptainer registry login \
--username "${DT4ACC_REGISTRY_USER}" \
--password-stdin \
oras://gitlab-registry.synchrotron-soleil.fr

- name: Pull dt4acc twin image
run: |
mkdir -p "${RUNNER_TEMP}/apptainer"
apptainer pull --force --disable-cache \
"${RUNNER_TEMP}/apptainer/dt4acc-soleil-twin.sif" \
"${DT4ACC_IMAGE_URI}"

- name: Start dt4acc twin
run: |
LOG_FILE="${RUNNER_TEMP}/dt4acc-twin.log"
PID_FILE="${RUNNER_TEMP}/dt4acc-twin.pid"

apptainer run \
--bind "${GITHUB_WORKSPACE}/tests/integration/data:/data:ro" \
"${RUNNER_TEMP}/apptainer/dt4acc-soleil-twin.sif" \
--force-kill-db \
--tango-host "${TANGO_HOST}" \
--accelerator-setup-file "/data/fodo_1gev_6d_pyaml.json" \
--lattice-file "/data/fodo_1gev_6d.m" \
> "${LOG_FILE}" 2>&1 &

echo "$!" > "${PID_FILE}"
export TWIN_PID="$(cat "${PID_FILE}")"
export LOG_FILE

timeout 900 bash -c '
until grep -q "Calculation heartbeat: simulator/ringsimulator/ringsimulator reachable" "${LOG_FILE}"; do
if ! kill -0 "${TWIN_PID}" 2>/dev/null; then
cat "${LOG_FILE}"
exit 1
fi
sleep 2
done
'

- name: Run pyAML dt4acc smoke test
env:
PYAML_DT4ACC_INTEGRATION: "1"
run: |
python -m pytest -v tests/integration/test_dt4acc_twin_smoke.py

- name: Stop dt4acc twin
if: always()
run: |
PID_FILE="${RUNNER_TEMP}/dt4acc-twin.pid"
if [ -f "${PID_FILE}" ]; then
kill "$(cat "${PID_FILE}")" 2>/dev/null || true
wait "$(cat "${PID_FILE}")" 2>/dev/null || true
fi
if [ -f "${RUNNER_TEMP}/dt4acc-twin.log" ]; then
tail -n 200 "${RUNNER_TEMP}/dt4acc-twin.log" || true
fi

- name: Upload dt4acc logs
if: always()
uses: actions/upload-artifact@v4
with:
name: dt4acc-twin-log
path: ${{ runner.temp }}/dt4acc-twin.log
5 changes: 5 additions & 0 deletions pyproject.toml
Original file line number Diff line number Diff line change
Expand Up @@ -126,3 +126,8 @@ skip-magic-trailing-comma = false
python_version = "3.11"
strict = false
ignore_missing_imports = true

[tool.pytest.ini_options]
markers = [
"integration: tests requiring an external integration runtime",
]
5 changes: 5 additions & 0 deletions tests/conftest.py
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
import importlib
import importlib.machinery
import os
import pathlib
import sys
import types
Expand Down Expand Up @@ -215,6 +216,10 @@ def _installed_test_packages(

@pytest.fixture(scope="session", autouse=True)
def install_default_test_packages():
if os.environ.get("PYAML_DT4ACC_INTEGRATION") == "1":
yield
return

package_paths = [spec.local_path.resolve() for spec in _TEST_PACKAGES.values()]
with _installed_test_packages(
package_paths,
Expand Down
172 changes: 172 additions & 0 deletions tests/integration/data/fodo_1gev_6d.m
Original file line number Diff line number Diff line change
@@ -0,0 +1,172 @@
function ring = fodo_1gev_6d()
ring = {...
atringparam('FODO_1GeV_6D', 1000000000.0, 1, 'Particle', struct('name', 'relativistic', 'rest_energy', 0.0, 'charge', -1.0), 'beam_current', 0.0, 'cell_harmnumber', 90.0);...
atrfcavity('RF_001', 0.0, 300000.0, 351319286.71874994, 90, 1000000000.0, 'UUID', 'RF_001_cc245d84ca2b4ba9b54051069a4cfb8f');...
atquadrupole('QF_001', 0.4, 1.2580503144087112, 'UUID', 'QF_001_f2013521b99e4a76bed1db7ec67464b0');...
atsextupole('SF_001', 0.1, 2.1149384071729247, 'UUID', 'SF_001_f934c7cf2c704132acfce86bc2419e36');...
atdrift('DRs_001', 0.4);...
atsbend('B_001', 1.0, 0.19634954084936207, 0.0, 'UUID', 'B_001_6182cf9bb0184f0bb9afc6655b5a6be6');...
atdrift('DR_001', 0.5);...
atquadrupole('QD_001', 0.4, -1.3094253462460304, 'UUID', 'QD_001_15812e1906ee4bc7b94abb8ccd910f5b');...
atsextupole('SD_001', 0.1, -3.4137638639939585, 'UUID', 'SD_001_4e39bd9617e7428486da49e4b5cc3981');...
atdrift('DRs_002', 0.4);...
atsbend('B_002', 1.0, 0.19634954084936207, 0.0, 'UUID', 'B_002_8fd91332121b43c79d649fb2a1a18ca6');...
atdrift('DR_002', 0.5);...
atquadrupole('QF_002', 0.4, 1.2580503144087112, 'UUID', 'QF_002_d8a6e63c07c94aed87878d113cf22194');...
atsextupole('SF_002', 0.1, 2.1149384071729247, 'UUID', 'SF_002_f7c48af5504649a09b8e9434b2509ce4');...
atdrift('DRs_003', 0.4);...
atsbend('B_003', 1.0, 0.19634954084936207, 0.0, 'UUID', 'B_003_fb4cc089236e4345b0a3f4a39ae6f49b');...
atdrift('DR_003', 0.5);...
atquadrupole('QD_002', 0.4, -1.3094253462460304, 'UUID', 'QD_002_c212a1d7ea41484f925303959213cc32');...
atsextupole('SD_002', 0.1, -3.4137638639939585, 'UUID', 'SD_002_178b0b0cfcc046c6ac9a1eac2328963e');...
atdrift('DRs_004', 0.4);...
atsbend('B_004', 1.0, 0.19634954084936207, 0.0, 'UUID', 'B_004_00d0b0b840a74028b751a6a7f72025fa');...
atdrift('DR_004', 0.5);...
atquadrupole('QF_003', 0.4, 1.2580503144087112, 'UUID', 'QF_003_d6bf77b8f23b45e0b1e96bb88f7b3d40');...
atsextupole('SF_003', 0.1, 2.1149384071729247, 'UUID', 'SF_003_bd75202a28b243d0bc604fa6e8ad0dd2');...
atdrift('DRs_005', 0.4);...
atsbend('B_005', 1.0, 0.19634954084936207, 0.0, 'UUID', 'B_005_270a6ec2a6ea465a959a5f47f2434fb0');...
atdrift('DR_005', 0.5);...
atquadrupole('QD_003', 0.4, -1.3094253462460304, 'UUID', 'QD_003_ad775f317e7b4408a72e09c7db4236ad');...
atsextupole('SD_003', 0.1, -3.4137638639939585, 'UUID', 'SD_003_63a3ec9ceeef453f8e793acc437ce116');...
atdrift('DRs_006', 0.4);...
atsbend('B_006', 1.0, 0.19634954084936207, 0.0, 'UUID', 'B_006_730f427ca9814851801be691784b96e9');...
atdrift('DR_006', 0.5);...
atquadrupole('QF_004', 0.4, 1.2580503144087112, 'UUID', 'QF_004_ce31bb358fad4cc7aadb86711031acd0');...
atsextupole('SF_004', 0.1, 2.1149384071729247, 'UUID', 'SF_004_faa5bb6858e64051a54f4f01340684e6');...
atdrift('DRs_007', 0.4);...
atsbend('B_007', 1.0, 0.19634954084936207, 0.0, 'UUID', 'B_007_c74ee44ff12e425b9bcb21277c6efc59');...
atdrift('DR_007', 0.5);...
atquadrupole('QD_004', 0.4, -1.3094253462460304, 'UUID', 'QD_004_82625fab961945c0aba57174ebcbf51f');...
atsextupole('SD_004', 0.1, -3.4137638639939585, 'UUID', 'SD_004_3e0e59ac94f945f2be40eccc30f3a2d3');...
atdrift('DRs_008', 0.4);...
atsbend('B_008', 1.0, 0.19634954084936207, 0.0, 'UUID', 'B_008_47727693f2b14c6089c1b12a0331c942');...
atdrift('DR_008', 0.5);...
atquadrupole('QF_005', 0.4, 1.2580503144087112, 'UUID', 'QF_005_d812a0f116044852a2dfc809ca0b87bf');...
atsextupole('SF_005', 0.1, 2.1149384071729247, 'UUID', 'SF_005_ab16d309e1e341e58d7ae1598098bb69');...
atdrift('DRs_009', 0.4);...
atsbend('B_009', 1.0, 0.19634954084936207, 0.0, 'UUID', 'B_009_ddd2050e98164ab9b3d3b052188a3247');...
atdrift('DR_009', 0.5);...
atquadrupole('QD_005', 0.4, -1.3094253462460304, 'UUID', 'QD_005_03b6d72e666d4632b6e9a3c2b15ceca7');...
atsextupole('SD_005', 0.1, -3.4137638639939585, 'UUID', 'SD_005_1e16f88b09834fd6bd6cf9ef7de62dbe');...
atdrift('DRs_010', 0.4);...
atsbend('B_010', 1.0, 0.19634954084936207, 0.0, 'UUID', 'B_010_184685f07007416aa94cc3b7797433af');...
atdrift('DR_010', 0.5);...
atquadrupole('QF_006', 0.4, 1.2580503144087112, 'UUID', 'QF_006_d39cefd95c88492885796863d4df1b68');...
atsextupole('SF_006', 0.1, 2.1149384071729247, 'UUID', 'SF_006_09d95d77b39a463283b0660c4478c409');...
atdrift('DRs_011', 0.4);...
atsbend('B_011', 1.0, 0.19634954084936207, 0.0, 'UUID', 'B_011_66708404736c4a74bbd88f2776ba6757');...
atdrift('DR_011', 0.5);...
atquadrupole('QD_006', 0.4, -1.3094253462460304, 'UUID', 'QD_006_49e8c0b7e66348338865c77d9317c6bf');...
atsextupole('SD_006', 0.1, -3.4137638639939585, 'UUID', 'SD_006_284911364f3c44b2abdc13acb2df46b3');...
atdrift('DRs_012', 0.4);...
atsbend('B_012', 1.0, 0.19634954084936207, 0.0, 'UUID', 'B_012_63cc84ca3a804b889757df9285fd44ac');...
atdrift('DR_012', 0.5);...
atquadrupole('QF_007', 0.4, 1.2580503144087112, 'UUID', 'QF_007_7414601f613f4115b9fe0b78eceaa2ce');...
atsextupole('SF_007', 0.1, 2.1149384071729247, 'UUID', 'SF_007_b3fa2def44a24425a5ad414abc5bbca1');...
atdrift('DRs_013', 0.4);...
atsbend('B_013', 1.0, 0.19634954084936207, 0.0, 'UUID', 'B_013_046c935da3f54e75beade9ed565219ad');...
atdrift('DR_013', 0.5);...
atquadrupole('QD_007', 0.4, -1.3094253462460304, 'UUID', 'QD_007_79fa1ac91a7f43eda443200923990327');...
atsextupole('SD_007', 0.1, -3.4137638639939585, 'UUID', 'SD_007_3b05e519bdcd4fc4b3b8dc42c2c1cb55');...
atdrift('DRs_014', 0.4);...
atsbend('B_014', 1.0, 0.19634954084936207, 0.0, 'UUID', 'B_014_2ead304932de4ce4b6382bbac997c85a');...
atdrift('DR_014', 0.5);...
atquadrupole('QF_008', 0.4, 1.2580503144087112, 'UUID', 'QF_008_b3d3db8e1c9e4e8c9eb2846730bd81ea');...
atsextupole('SF_008', 0.1, 2.1149384071729247, 'UUID', 'SF_008_00a14620b0a5428b821ddb84d2639e5c');...
atdrift('DRs_015', 0.4);...
atsbend('B_015', 1.0, 0.19634954084936207, 0.0, 'UUID', 'B_015_b7dd580aac5147a3af0bb2817408e27e');...
atdrift('DR_015', 0.5);...
atquadrupole('QD_008', 0.4, -1.3094253462460304, 'UUID', 'QD_008_1cb9b3401b644658908260616570424d');...
atsextupole('SD_008', 0.1, -3.4137638639939585, 'UUID', 'SD_008_3b849a66bca1453cac95fa0ccba58166');...
atdrift('DRs_016', 0.4);...
atsbend('B_016', 1.0, 0.19634954084936207, 0.0, 'UUID', 'B_016_b83b8bedbb624a8ebfa7f6166daf3613');...
atdrift('DR_016', 0.5);...
atquadrupole('QF_009', 0.4, 1.2580503144087112, 'UUID', 'QF_009_441bf7bdfe9c443c8a55c1a58cb1caf5');...
atsextupole('SF_009', 0.1, 2.1149384071729247, 'UUID', 'SF_009_6f725f3f495f428696a8419b73f22774');...
atdrift('DRs_017', 0.4);...
atsbend('B_017', 1.0, 0.19634954084936207, 0.0, 'UUID', 'B_017_04ad34df6c2e4dfca0d6fb797d68df69');...
atdrift('DR_017', 0.5);...
atquadrupole('QD_009', 0.4, -1.3094253462460304, 'UUID', 'QD_009_232f21c02a03457698d31ec2d4265a02');...
atsextupole('SD_009', 0.1, -3.4137638639939585, 'UUID', 'SD_009_cf86e64cfe764c12b94262c41ceabbfb');...
atdrift('DRs_018', 0.4);...
atsbend('B_018', 1.0, 0.19634954084936207, 0.0, 'UUID', 'B_018_0b98487fcf314e7e8452dc7399397835');...
atdrift('DR_018', 0.5);...
atquadrupole('QF_010', 0.4, 1.2580503144087112, 'UUID', 'QF_010_94782da4ed5e4898b91d7e864140c277');...
atsextupole('SF_010', 0.1, 2.1149384071729247, 'UUID', 'SF_010_f626388a02d64cfd83c9b1614982a5fb');...
atdrift('DRs_019', 0.4);...
atsbend('B_019', 1.0, 0.19634954084936207, 0.0, 'UUID', 'B_019_7d367c5a53bb4df4b7ecde53d5604f53');...
atdrift('DR_019', 0.5);...
atquadrupole('QD_010', 0.4, -1.3094253462460304, 'UUID', 'QD_010_56f8b47113df4cec8b2fc3ab38c69869');...
atsextupole('SD_010', 0.1, -3.4137638639939585, 'UUID', 'SD_010_eafccc3719664195b4107df7527a8a0a');...
atdrift('DRs_020', 0.4);...
atsbend('B_020', 1.0, 0.19634954084936207, 0.0, 'UUID', 'B_020_fa8a3d3ea2814c44b7815c8a5cd9d933');...
atdrift('DR_020', 0.5);...
atquadrupole('QF_011', 0.4, 1.2580503144087112, 'UUID', 'QF_011_b575ed5454c54128b2ed3d6b7e64ddad');...
atsextupole('SF_011', 0.1, 2.1149384071729247, 'UUID', 'SF_011_bd73fc4fbc0640efb117cac154b34c33');...
atdrift('DRs_021', 0.4);...
atsbend('B_021', 1.0, 0.19634954084936207, 0.0, 'UUID', 'B_021_0d732787af974b9eb0d4c1cc70db1a3d');...
atdrift('DR_021', 0.5);...
atquadrupole('QD_011', 0.4, -1.3094253462460304, 'UUID', 'QD_011_ae7b2c76f21b429c962ff3c33a38cd70');...
atsextupole('SD_011', 0.1, -3.4137638639939585, 'UUID', 'SD_011_773d914fde034e8697ac966f74ca0611');...
atdrift('DRs_022', 0.4);...
atsbend('B_022', 1.0, 0.19634954084936207, 0.0, 'UUID', 'B_022_96a000342e284ca68faaecbcd4b0904a');...
atdrift('DR_022', 0.5);...
atquadrupole('QF_012', 0.4, 1.2580503144087112, 'UUID', 'QF_012_cb52fb6f374840b0a50180a089da49d1');...
atsextupole('SF_012', 0.1, 2.1149384071729247, 'UUID', 'SF_012_02daf05ef4ab46ea86bdb3be90162251');...
atdrift('DRs_023', 0.4);...
atsbend('B_023', 1.0, 0.19634954084936207, 0.0, 'UUID', 'B_023_ffdf1ba0d350458fb3def9db81636f68');...
atdrift('DR_023', 0.5);...
atquadrupole('QD_012', 0.4, -1.3094253462460304, 'UUID', 'QD_012_29f2185aa29a4c02be3bbfdd5bad13e3');...
atsextupole('SD_012', 0.1, -3.4137638639939585, 'UUID', 'SD_012_ff9262ea95744358b360235d7a459cec');...
atdrift('DRs_024', 0.4);...
atsbend('B_024', 1.0, 0.19634954084936207, 0.0, 'UUID', 'B_024_e1fb35bf800a43448163b0cf01569c19');...
atdrift('DR_024', 0.5);...
atquadrupole('QF_013', 0.4, 1.2580503144087112, 'UUID', 'QF_013_2793a62cd78744c9ab4ca5e2843a72a2');...
atsextupole('SF_013', 0.1, 2.1149384071729247, 'UUID', 'SF_013_4532d63397d644d28e1af1a480a60c07');...
atdrift('DRs_025', 0.4);...
atsbend('B_025', 1.0, 0.19634954084936207, 0.0, 'UUID', 'B_025_2ce6a646af5642e0afc30d9f79863f48');...
atdrift('DR_025', 0.5);...
atquadrupole('QD_013', 0.4, -1.3094253462460304, 'UUID', 'QD_013_03843b2e6ee24e16aa6572f5cb18f4a8');...
atsextupole('SD_013', 0.1, -3.4137638639939585, 'UUID', 'SD_013_ef033612a3274ef3ab886afd81614dca');...
atdrift('DRs_026', 0.4);...
atsbend('B_026', 1.0, 0.19634954084936207, 0.0, 'UUID', 'B_026_8651fc68043842628e6ee1d25af0424c');...
atdrift('DR_026', 0.5);...
atquadrupole('QF_014', 0.4, 1.2580503144087112, 'UUID', 'QF_014_c09c7e604b3a41fa818b44d04c844b25');...
atsextupole('SF_014', 0.1, 2.1149384071729247, 'UUID', 'SF_014_bf4393ec53954372bd5e4f140491465b');...
atdrift('DRs_027', 0.4);...
atsbend('B_027', 1.0, 0.19634954084936207, 0.0, 'UUID', 'B_027_c832ae3f14b14804a63bce49c896f737');...
atdrift('DR_027', 0.5);...
atquadrupole('QD_014', 0.4, -1.3094253462460304, 'UUID', 'QD_014_62633bc5afcd4fc9a19de70a983baa5c');...
atsextupole('SD_014', 0.1, -3.4137638639939585, 'UUID', 'SD_014_78a18b94b6f1422fb69dbcbd2ae90d67');...
atdrift('DRs_028', 0.4);...
atsbend('B_028', 1.0, 0.19634954084936207, 0.0, 'UUID', 'B_028_25d59d6cbd90410c9ba5ed8424d442d1');...
atdrift('DR_028', 0.5);...
atquadrupole('QF_015', 0.4, 1.2580503144087112, 'UUID', 'QF_015_63634bfdccc44de586db6ee28071ccb4');...
atsextupole('SF_015', 0.1, 2.1149384071729247, 'UUID', 'SF_015_a988680835664d109306ad1694a48382');...
atdrift('DRs_029', 0.4);...
atsbend('B_029', 1.0, 0.19634954084936207, 0.0, 'UUID', 'B_029_dc2c0a36c7d64072b3e597a3b40f4b3e');...
atdrift('DR_029', 0.5);...
atquadrupole('QD_015', 0.4, -1.3094253462460304, 'UUID', 'QD_015_b2cc0d3ab8f741729a7abf3d9426a958');...
atsextupole('SD_015', 0.1, -3.4137638639939585, 'UUID', 'SD_015_8b7f143df262464e9f5c1eae4b83ce14');...
atdrift('DRs_030', 0.4);...
atsbend('B_030', 1.0, 0.19634954084936207, 0.0, 'UUID', 'B_030_225d0545f13b49b58c1ab5222727ae20');...
atdrift('DR_030', 0.5);...
atquadrupole('QF_016', 0.4, 1.2580503144087112, 'UUID', 'QF_016_965422d59ef3488f84c68f5ecaee6c6b');...
atsextupole('SF_016', 0.1, 2.1149384071729247, 'UUID', 'SF_016_e67c83cfbce2433f9152de49f928d25d');...
atdrift('DRs_031', 0.4);...
atsbend('B_031', 1.0, 0.19634954084936207, 0.0, 'UUID', 'B_031_8e33e0d3bfdf491da8ca3d8dd66e1b81');...
atdrift('DR_031', 0.5);...
atquadrupole('QD_016', 0.4, -1.3094253462460304, 'UUID', 'QD_016_63fce39354a946818c2bfd76adb61760');...
atsextupole('SD_016', 0.1, -3.4137638639939585, 'UUID', 'SD_016_626878061df544a08c4c061e57a4e3a1');...
atdrift('DRs_032', 0.4);...
atsbend('B_032', 1.0, 0.19634954084936207, 0.0, 'UUID', 'B_032_2d3c2be8fe5f41abb120ab3438a4ef66');...
atdrift('DR_032', 0.5);...
};
function v=False()
v=false;
end
function v=True()
v=true;
end
end
Loading
Loading