Skip to content

Standardise config client and fix tests dependent on order they are ran#2099

Open
oliwenmandiamond wants to merge 36 commits into
mainfrom
standardise_config_server_in_tests
Open

Standardise config client and fix tests dependent on order they are ran#2099
oliwenmandiamond wants to merge 36 commits into
mainfrom
standardise_config_server_in_tests

Conversation

@oliwenmandiamond

@oliwenmandiamond oliwenmandiamond commented Jun 22, 2026

Copy link
Copy Markdown
Contributor

Fixes #2098

Instructions to reviewer on how to test:

  1. Run a few dodal/tests/common/beamlines/test_device_instantiation.py::test_device_creation[iXX] in main branch and this branch. Confirm they now pass and doesn't depend on order.
  2. Confirm tests pass
  3. Confirm added documentation makes sense

Checks for reviewer

  • Would the PR title make sense to a scientist on a set of release notes
  • If a new device has been added does it follow the standards
  • If changing the API for a pre-existing device, ensure that any beamlines using this device have updated their Bluesky plans accordingly
  • Have the connection tests for the relevant beamline(s) been run via dodal connect ${BEAMLINE}

@oliwenmandiamond oliwenmandiamond changed the title Standardise config server in tests Standardise config client in tests Jun 22, 2026
@codecov

codecov Bot commented Jun 23, 2026

Copy link
Copy Markdown

Codecov Report

✅ All modified and coverable lines are covered by tests.
✅ Project coverage is 99.15%. Comparing base (c101e17) to head (bafdbf8).

Additional details and impacted files
@@           Coverage Diff           @@
##             main    #2099   +/-   ##
=======================================
  Coverage   99.15%   99.15%           
=======================================
  Files         346      346           
  Lines       13536    13541    +5     
=======================================
+ Hits        13422    13427    +5     
  Misses        114      114           

☔ View full report in Codecov by Harness.
📢 Have feedback on the report? Share it here.

🚀 New features to boost your workflow:
  • ❄️ Test Analytics: Detect flaky tests, report on failures, and find test suite problems.

@oliwenmandiamond oliwenmandiamond changed the title Standardise config client in tests Standardise config client and fix tests dependent on order they are ran Jun 24, 2026
@oliwenmandiamond oliwenmandiamond marked this pull request as ready for review June 24, 2026 12:30
@oliwenmandiamond oliwenmandiamond requested a review from a team as a code owner June 24, 2026 12:30
@tpoliaw tpoliaw requested a review from DominicOram June 25, 2026 13:37

@DominicOram DominicOram left a comment

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.

Thanks, I couldn't reproduce the flaky tests issue but I think this cleans things up a bit anyway. Couple of spelling mistakes, I would suggest installing https://marketplace.visualstudio.com/items?itemName=streetsidesoftware.code-spell-checker


@devices.fixture
def iconfig_client() -> ConfigClient:
return ConfigClient()

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: In other beamlines this fixture then calls set_config_client. I know it's not strictly required as you're not relying on get_config_client() but I would consider doing it here (and the other beamlines you've changed) anyway as you may later expect it there


@devices.fixture
def jconfig_client() -> ConfigClient:
return ConfigClient(url="https://daq-config.diamond.ac.uk")

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: This is the default URL, why are we specifying it?

@pytest.fixture
async def oav() -> OAV:
oav_config = OAVConfig(TEST_OAV_ZOOM_LEVELS, ConfigClient(""))
async def oav(mock_config_client: ConfigClient) -> OAV:

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.

Should: This fixture isn't actually used anywhere, just remove it.

# We need to find a better way of integrating this, see https://github.com/DiamondLightSource/mx-bluesky/issues/183
@pytest.mark.skip(reason="Don't want to actually take snapshots during testing.")
def test_grid_overlay(run_engine: RunEngine):
def test_grid_overlay(run_engine: RunEngine, mock_config_client: ConfigClient):

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.

This test is failing on main anyway - I've made #2108.


def fake_config_server_get_file_contents(
filepath: str | Path,
# Tests can register a specific file path with an assoicated file contents to model

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.

Suggested change
# Tests can register a specific file path with an assoicated file contents to model
# Tests can register a specific file path with an associated file contents to model

Comment on lines +126 to +159
Beamlines and devices may depend on the daq-config-server `ConfigClient` to retrieve configuration files. These files are often stored on the DLS filesystem and contain configuration data that determines device behaviour.

For example, an insertion device may use a calibration file containing polynomial coefficients that convert photon energy into insertion device gap for different polarisation modes. A device may retrieve this information using a `ConfigClient`:

```python
from pathlib import Path

from daq_config_server import ConfigClient

from dodal.device_manager import DeviceManager
from dodal.devices.my_device import MyDevice

LOOKUPTABLE_DIR = (
"/dls_sw/iXX/software/gda/workspace_git/"
"gda-diamond.git/configurations/iXX/lookupTables"
)
LOOKUP_FILE_NAME = "JIDEnergy2GapCalibrations.csv"

devices = DeviceManager()


@devices.fixture
def config_client() -> ConfigClient:
return ConfigClient()


@devices.factory()
def my_device(config_client: ConfigClient) -> MyDevice:
return MyDevice(
config_client=config_client,
path=Path(LOOKUPTABLE_DIR, LOOKUP_FILE_NAME),
)
```

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.

Should: I like this bit of documentation but it doesn't belong in the "how to write tests" document. It's more about how to use the config server


### Registering a custom parser

Some configuration file formats are not JSON-based and require custom parsing logic. For these cases, tests can register a parser using `MOCK_CONFIG_CLIENT_PATH_TO_MODEL_CONVERSION`.

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.

Should: If you accept my suggestion this documentation needs changing a bit

set(all_beamline_modules()),
indirect=True,
)
# Increase timeout for this specific test as running inividually can take over a second

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.

Suggested change
# Increase timeout for this specific test as running inividually can take over a second
# Increase timeout for this specific test as running individually can take over a second

set(all_beamline_modules()),
indirect=True,
)
# Increase timeout for this specific test as running inividually can take over a second

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.

Suggested change
# Increase timeout for this specific test as running inividually can take over a second
# Increase timeout for this specific test as running individually can take over a second

1. Replaces `ConfigClient.get_file_contents()` with the `mock_config_client` implementation.
2. Replaces known module-level file path constants with paths to test data files.

### Mocking `ConfigClient`

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: I'm not sure why we need to document this? Why does someone writing new tests need to know about it?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Test fails depending on the order they are run

3 participants