Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
42 commits
Select commit Hold shift + click to select a range
97783aa
Convert test beamlineParameters files
jacob720 Dec 9, 2025
4cae7d8
Add mock config server
jacob720 Dec 9, 2025
4c37ed9
Pin dodal
jacob720 Dec 10, 2025
9136e23
Fix
jacob720 Jan 12, 2026
2a89044
Require newest daq-config-server
jacob720 Jan 12, 2026
26aa661
Fix against dodal
jacob720 Jan 23, 2026
1605fca
Remove redundant fixture
jacob720 Jan 26, 2026
13c2a2b
Merge branch 'main' into 1504_read_beamlineParameters_through_config_…
jacob720 Jan 26, 2026
8810f9f
Merge branch 'main' into 1504_read_beamlineParameters_through_config_…
jacob720 Feb 5, 2026
623de3b
Fix lint
jacob720 Feb 5, 2026
230bcd8
Merge branch 'main' into 1504_read_beamlineParameters_through_config_…
jacob720 Feb 5, 2026
af04fae
Merge branch 'main' into 1504_read_beamlineParameters_through_config_…
jacob720 Feb 11, 2026
bf3d105
Use config server fixtures from dodal and patch beamline environment
jacob720 Feb 11, 2026
fdaed05
Reduce use of get_beamline_name default
jacob720 Feb 11, 2026
992b067
Fix tests
jacob720 Feb 13, 2026
d53c9f9
Merge branch 'main' into 1504_read_beamlineParameters_through_config_…
jacob720 Feb 13, 2026
095a052
Fix
jacob720 Feb 13, 2026
f70f9b6
Merge branch 'main' into 1504_read_beamlineParameters_through_config_…
jacob720 Feb 23, 2026
6f17235
Merge branch 'main' into 1504_read_beamlineParameters_through_config_…
jacob720 Mar 2, 2026
5bd5224
Use config server to read pitch and roll config
jacob720 Dec 9, 2025
9a555a3
Fix tests and test data
jacob720 Dec 9, 2025
fe31780
Pin dodal and daq-config-server
jacob720 Dec 9, 2025
90a847c
Use specific lut models for each undulator lut
jacob720 Jan 6, 2026
1b566f7
Fix for columns becoming a property
jacob720 Jan 6, 2026
85c2752
Use latest config server version
jacob720 Jan 12, 2026
c887f44
Set BEAMLINE env variable in undulator fixture
jacob720 Mar 2, 2026
df5e56b
Merge branch 'main' into 1504_read_beamlineParameters_through_config_…
jacob720 Mar 10, 2026
92bc727
Merge branch 'main' into 1504_read_beamlineParameters_through_config_…
jacob720 Mar 12, 2026
a60d219
Merge branch '1504_read_beamlineParameters_through_config_server' int…
jacob720 Mar 12, 2026
5d46d8f
Merge branch 'main' into use_daq_config_server
jacob720 Mar 17, 2026
33f5b44
Use i03 config client
jacob720 Mar 17, 2026
d6b77ad
Merge branch 'main' into use_daq_config_server
jacob720 Mar 18, 2026
a4c34c0
Use beamline config client constants
jacob720 Mar 18, 2026
ba1158d
Update lockfile
jacob720 Mar 18, 2026
6522c4c
Remove unneeded patch
jacob720 Mar 18, 2026
2a1ffb6
Add system tests
jacob720 Mar 19, 2026
8e36263
Fix lint
jacob720 Mar 20, 2026
001cce4
Use new get_config_client and remove where possible
jacob720 Mar 23, 2026
3ede4ee
Fix tests
jacob720 Mar 23, 2026
93b6d75
Merge branch 'main' into use_daq_config_server
jacob720 Mar 23, 2026
161d678
Update lockfile
jacob720 Mar 23, 2026
cbec4e9
Fix tests
jacob720 Mar 24, 2026
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
5 changes: 1 addition & 4 deletions conftest.py
Original file line number Diff line number Diff line change
Expand Up @@ -10,10 +10,7 @@
environ["HYPERION_TEST_MODE"] = "true"


pytest_plugins = [
"dodal.testing.fixtures.run_engine",
"dodal.testing.fixtures.config_server",
]
pytest_plugins = ["dodal.testing.fixtures.run_engine"]


def pytest_addoption(parser):
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,14 +2,13 @@
I04FeatureSettings,
)
from dodal.beamlines.i04 import DAQ_CONFIGURATION_PATH
from dodal.common.beamlines.config_client import get_config_client
from dodal.common.beamlines.beamline_utils import get_config_client

GDA_DOMAIN_PROPERTIES_PATH = DAQ_CONFIGURATION_PATH + "/domain/domain.properties"


Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

could consider renaming the file here to config_client

def get_i04_feature_settings() -> I04FeatureSettings:
config_client = get_config_client("i04")
return config_client.get_file_contents(
return get_config_client().get_file_contents(
GDA_DOMAIN_PROPERTIES_PATH,
desired_return_type=I04FeatureSettings,
reset_cached_result=True,
Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,4 @@
import bluesky.plan_stubs as bps
from dodal.common.beamlines.config_client import get_config_client
from dodal.devices.beamlines.i03.undulator_dcm import UndulatorDCM
from dodal.devices.focusing_mirror import (
FocusingMirrorWithStripes,
Expand All @@ -9,7 +8,6 @@
from dodal.devices.util.adjuster_plans import lookup_table_adjuster
from dodal.devices.util.lookup_tables import (
linear_interpolation_lut,
parse_lookup_table,
)

from mx_bluesky.common.utils.log import LOGGER
Expand All @@ -26,12 +24,8 @@ def _apply_and_wait_for_voltages_to_settle(
stripe: MirrorStripe,
mirror_voltages: MirrorVoltages,
):
config_server = get_config_client("i03")
config_dict = config_server.get_file_contents(
mirror_voltages.voltage_lookup_table_path, dict
)
# sample mode is the only mode supported
sample_data = config_dict["sample"]
sample_data = mirror_voltages.voltage_lookup_table["sample"]
if stripe == MirrorStripe.BARE:
stripe_key = "bare"
elif stripe == MirrorStripe.RHODIUM:
Expand Down Expand Up @@ -114,12 +108,11 @@ def adjust_dcm_pitch_roll_vfm_from_lut(
d_spacing_a: float = yield from bps.rd(
undulator_dcm.dcm_ref().crystal_metadata_d_spacing_a
)

bragg_deg = energy_to_bragg_angle(energy_kev, d_spacing_a)
LOGGER.info(f"Target Bragg angle = {bragg_deg} degrees")
dcm_pitch_adjuster = lookup_table_adjuster(
linear_interpolation_lut(
*parse_lookup_table(undulator_dcm.pitch_energy_table_path)
),
linear_interpolation_lut(*undulator_dcm.pitch_energy_table.columns),
dcm.xtal_1.pitch_in_mrad,
bragg_deg,
)
Expand All @@ -129,9 +122,7 @@ def adjust_dcm_pitch_roll_vfm_from_lut(

# DCM Roll
dcm_roll_adjuster = lookup_table_adjuster(
linear_interpolation_lut(
*parse_lookup_table(undulator_dcm.roll_energy_table_path)
),
linear_interpolation_lut(*undulator_dcm.roll_energy_table.columns),
dcm.xtal_1.roll_in_mrad,
bragg_deg,
)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,14 +2,13 @@
HyperionFeatureSettings,
)
from dodal.beamlines.i03 import DAQ_CONFIGURATION_PATH
from dodal.common.beamlines.config_client import get_config_client
from dodal.common.beamlines.beamline_utils import get_config_client

GDA_DOMAIN_PROPERTIES_PATH = DAQ_CONFIGURATION_PATH + "/domain/domain.properties"


def get_hyperion_feature_settings() -> HyperionFeatureSettings:
config_client = get_config_client("i03")
return config_client.get_file_contents(
return get_config_client().get_file_contents(
GDA_DOMAIN_PROPERTIES_PATH,
desired_return_type=HyperionFeatureSettings,
)
5 changes: 2 additions & 3 deletions src/mx_bluesky/hyperion/utils/context.py
Original file line number Diff line number Diff line change
@@ -1,6 +1,5 @@
from blueapi.core import BlueskyContext
from dodal.common.beamlines.beamline_utils import clear_devices
from dodal.common.beamlines.config_client import get_config_client
from dodal.common.beamlines.beamline_utils import clear_devices, get_config_client
from dodal.utils import collect_factories, get_beamline_based_on_environment_variable


Expand All @@ -18,7 +17,7 @@ def clear_all_device_caches(context: BlueskyContext):
if hasattr(f, "cache_clear"):
f.cache_clear() # type: ignore

get_config_client("i03").reset_cache()
get_config_client().reset_cache()


def setup_devices(context: BlueskyContext, dev_mode: bool):
Expand Down
74 changes: 17 additions & 57 deletions tests/conftest.py
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,6 @@
import os
import sys
from collections.abc import Callable, Generator, Sequence
from contextlib import ExitStack
from functools import partial
from pathlib import Path
from types import ModuleType
Expand All @@ -18,11 +17,15 @@
import pytest
from bluesky.simulators import RunEngineSimulator
from bluesky.utils import Msg, MsgGenerator
from daq_config_server import ConfigClient
from dodal.beamlines import aithre, i03
from dodal.common.beamlines import beamline_utils
from dodal.common.beamlines.beamline_utils import clear_devices
from dodal.common.beamlines.beamline_utils import (
clear_config_client,
clear_devices,
set_config_client,
)
from dodal.common.beamlines.commissioning_mode import set_commissioning_signal
from dodal.common.beamlines.config_client import get_config_client
from dodal.devices.aperturescatterguard import (
AperturePosition,
ApertureScatterguard,
Expand All @@ -41,6 +44,7 @@
from dodal.devices.beamlines.i03 import Beamstop, BeamstopPositions
from dodal.devices.beamlines.i03.beamsize import Beamsize
from dodal.devices.beamlines.i03.dcm import DCM
from dodal.devices.beamlines.i03.undulator_dcm import UndulatorDCM
from dodal.devices.beamlines.i04.transfocator import Transfocator
from dodal.devices.beamsize.beamsize import BeamsizeBase
from dodal.devices.detector.detector_motion import DetectorMotion
Expand All @@ -65,7 +69,6 @@
from dodal.devices.zocalo.zocalo_results import _NO_SAMPLE_ID
from dodal.log import LOGGER as DODAL_LOGGER
from dodal.log import set_up_all_logging_handlers
from dodal.testing.fixtures.config_server import fake_config_server_get_file_contents
from dodal.utils import AnyDeviceFactory, collect_factories
from event_model.documents import Event, EventDescriptor, RunStart, RunStop
from ophyd_async.core import (
Expand Down Expand Up @@ -116,7 +119,6 @@

pytest_plugins = ["tests.expeye_helpers"]

i03.DAQ_CONFIGURATION_PATH = "tests/test_data/test_daq_configuration"

TEST_GRAYLOG_PORT = 5555
TEST_VISIT = "cm1234-67"
Expand Down Expand Up @@ -221,13 +223,6 @@
}
]

MOCK_DAQ_CONFIG_PATH = "tests/test_data/test_daq_configuration"
mock_paths = [
("DAQ_CONFIGURATION_PATH", MOCK_DAQ_CONFIG_PATH),
("ZOOM_PARAMS_FILE", "tests/test_data/test_jCameraManZoomLevels.xml"),
("DISPLAY_CONFIG", f"{MOCK_DAQ_CONFIG_PATH}/display.configuration"),
]


@dataclass(frozen=True)
class SimConstants:
Expand Down Expand Up @@ -369,35 +364,9 @@ def _pass_on_mock(value: float, wait: bool):

@pytest.fixture
def beamline_parameters():
return fake_config_server_get_file_contents(
"tests/test_data/test_beamline_parameters.txt", dict
)


@pytest.fixture(autouse=True)
def i03_beamline_parameters():
"""Fix default i03 beamline parameters to refer to a test file not the /dls_sw folder"""
with patch.dict(
"dodal.common.beamlines.beamline_parameters.BEAMLINE_PARAMETER_PATHS",
{"i03": "tests/test_data/test_beamline_parameters.txt"},
) as params:
with ExitStack() as context_stack:
for context_mgr in [
patch(f"dodal.beamlines.i03.{name}", value, create=True)
for name, value in mock_paths
]:
context_stack.enter_context(context_mgr)
yield params


@pytest.fixture(autouse=True)
def test_beamline_parameters():
"""Fix default test beamline parameters to refer to a test file not the /dls_sw folder"""
with patch.dict(
"dodal.common.beamlines.beamline_parameters.BEAMLINE_PARAMETER_PATHS",
{"test": "tests/test_data/test_beamline_parameters.txt"},
) as params:
yield params
with Path("tests/test_data/test_beamline_parameters.txt").open("r") as f:
contents = f.read()
return json.loads(contents)


@pytest.fixture
Expand Down Expand Up @@ -670,7 +639,6 @@ def locate_gonio(_):
@pytest.fixture
def mirror_voltages():
voltages = i03.mirror_voltages.build(connect_immediately=True, mock=True)
voltages.voltage_lookup_table_path = "tests/test_data/test_mirror_focus.json"
for vc in voltages.vertical_voltages.values():
vc.set = MagicMock(side_effect=lambda _: completed_status())
for vc in voltages.horizontal_voltages.values():
Expand All @@ -680,8 +648,8 @@ def mirror_voltages():


@pytest.fixture
def undulator_dcm(sim_run_engine, dcm, undulator):
undulator_dcm = i03.undulator_dcm.build(
def undulator_dcm(sim_run_engine, dcm, undulator) -> Generator[UndulatorDCM]:
undulator_dcm: UndulatorDCM = i03.undulator_dcm.build(
connect_immediately=True,
mock=True,
daq_configuration_path="tests/test_data/test_daq_configuration",
Expand Down Expand Up @@ -1766,19 +1734,11 @@ def mock_alert_service():

@pytest.fixture()
def patch_beamline_env_variable(monkeypatch):
monkeypatch.setenv("BEAMLINE", "dev")
monkeypatch.setenv("BEAMLINE", "test")


@pytest.fixture(autouse=True)
def clear_cache():
get_config_client.cache_clear()


@pytest.fixture(autouse=True)
def patch_get_hyperion_feature_settings():
fake_path = "tests/test_data/test_domain_properties"
with patch(
"mx_bluesky.hyperion.external_interaction.config_server.GDA_DOMAIN_PROPERTIES_PATH",
str(fake_path),
):
yield
def reset_config_client():
set_config_client(ConfigClient(""))
yield
clear_config_client()
Empty file.
Empty file.
Original file line number Diff line number Diff line change
@@ -0,0 +1,42 @@
import pytest
from daq_config_server import ConfigClient
from daq_config_server.models.feature_settings.hyperion_feature_settings import (
HyperionFeatureSettings,
)
from dodal.common.beamlines.beamline_parameters import BEAMLINE_PARAMETER_PATHS
from dodal.common.beamlines.beamline_utils import get_config_client

from mx_bluesky.hyperion.external_interaction.config_server import (
GDA_DOMAIN_PROPERTIES_PATH,
)
from tests.system_tests.conftest import LOCAL_CONFIG_SERVER_URL


@pytest.mark.system_test
def test_can_get_file_from_real_config_server(config_client: ConfigClient):
filepath = "/dls_sw/i03/software/daq_configuration/testfile.txt"
result = config_client.get_file_contents(filepath, desired_return_type=str)
assert result == "this is for system tests"


@pytest.mark.system_test
def test_get_beamline_paramaters_from_real_config_server(
config_client: ConfigClient,
):
filepath = BEAMLINE_PARAMETER_PATHS["i03"]
config_client.get_file_contents(filepath, desired_return_type=dict)


@pytest.mark.system_test
def test_get_domain_proeprties_from_real_config_server(
config_client: ConfigClient,
):
filepath = GDA_DOMAIN_PROPERTIES_PATH
config_client.get_file_contents(
filepath, desired_return_type=HyperionFeatureSettings
)


@pytest.mark.system_test
def test_local_config_server_being_used_with_get_config_client():
assert get_config_client()._url == LOCAL_CONFIG_SERVER_URL
Original file line number Diff line number Diff line change
Expand Up @@ -10,12 +10,12 @@
from dodal.devices.smargon import Smargon
from ophyd_async.core import set_mock_value
from requests import get
from tests.conftest import SimConstants

from mx_bluesky.common.device_setup_plans.robot_load_unload import robot_unload
from mx_bluesky.hyperion.external_interaction.callbacks.robot_actions.ispyb_callback import (
RobotLoadISPyBCallback,
)
from tests.conftest import SimConstants


@pytest.mark.system_test
Expand Down
52 changes: 52 additions & 0 deletions tests/system_tests/conftest.py
Original file line number Diff line number Diff line change
Expand Up @@ -8,11 +8,15 @@

import pytest
from aiohttp import ClientResponse
from daq_config_server import ConfigClient
from dodal.beamlines import i03
from dodal.devices.beamlines.i03.undulator_dcm import UndulatorDCM
from dodal.devices.oav.oav_parameters import OAVConfigBeamCentre
from ophyd_async.core import AsyncStatus, set_mock_value
from PIL import Image

from tests.conftest import set_up_dcm

# Map all the case-sensitive column names from their normalised versions
DATA_COLLECTION_COLUMN_MAP = {
s.lower(): s
Expand Down Expand Up @@ -123,6 +127,8 @@
]
}

LOCAL_CONFIG_SERVER_URL = "http://0.0.0.0:8555"


def _system_test_env_error_message(env_var: str):
return RuntimeError(
Expand Down Expand Up @@ -234,3 +240,49 @@ def compare_comment(
match = re.search(" Zocalo processing took", actual_comment)
truncated_comment = actual_comment[: match.start()] if match else actual_comment
assert truncated_comment == expected_comment


@pytest.fixture
def config_client():
# Connects to real config server hosted locally
# Test files are stored in the hyperion-system-tests repo under ./daq_config_server/config/
# They have been mounted to match the paths in /dls_sw/i03/ so that the whitelist
# and file converter map behave as expected with no mocking needed.
# https://gitlab.diamond.ac.uk/MX-GDA/hyperion-system-testing/-/tree/add_daq_config_server/daq-config-server/config/?ref_type=heads
return ConfigClient(url=LOCAL_CONFIG_SERVER_URL)


@pytest.fixture(autouse=True)
def patch_i03_config_client():
"""Fix default i03 beamline parameters to refer to a test file not the /dls_sw folder"""
with patch.dict(
"dodal.common.beamlines.config_client.BEAMLINE_CONFIG_SERVER_ENDPOINTS",
{
"i03": LOCAL_CONFIG_SERVER_URL,
"test": LOCAL_CONFIG_SERVER_URL,
},
):
yield


@pytest.fixture(autouse=True)
def patch_get_hyperion_feature_settings():
path = "/dls_sw/i03/software/daq_configuration/domain/domain.properties"
with patch(
"mx_bluesky.hyperion.external_interaction.config_server.GDA_DOMAIN_PROPERTIES_PATH",
str(path),
):
yield


@pytest.fixture
def undulator_dcm(sim_run_engine, dcm, undulator) -> Generator[UndulatorDCM]:
undulator_dcm: UndulatorDCM = i03.undulator_dcm.build(
connect_immediately=True,
mock=True,
daq_configuration_path="/dls_sw/i03/software/daq_configuration/",
dcm=dcm,
undulator=undulator,
)
set_up_dcm(undulator_dcm.dcm_ref(), sim_run_engine)
yield undulator_dcm
Loading
Loading