From 6bb93855b0d505a579e36d3bf6f6841794832de2 Mon Sep 17 00:00:00 2001 From: Joseph Ware <53935796+DiamondJoseph@users.noreply.github.com> Date: Mon, 27 Oct 2025 13:54:32 +0000 Subject: [PATCH 01/11] Update copier template and transfer ownership --- .copier-answers.yml | 6 +++--- .github/CONTRIBUTING.md | 2 +- docs/reference/asyncapi.yaml | 4 ++-- pyproject.toml | 6 ++++-- 4 files changed, 10 insertions(+), 8 deletions(-) diff --git a/.copier-answers.yml b/.copier-answers.yml index d33a8e138..4ffed9b3c 100644 --- a/.copier-answers.yml +++ b/.copier-answers.yml @@ -1,8 +1,8 @@ # Changes here will be overwritten by Copier -_commit: 4.1.0 +_commit: 4.3.0 _src_path: https://github.com/DiamondLightSource/python-copier-template -author_email: callum.forrester@diamond.ac.uk -author_name: Callum Forrester +author_email: abigail.emery@diamond.ac.uk +author_name: Abigail Emery component_lifecycle: production component_owner: group:default/data-acquisition component_type: service diff --git a/.github/CONTRIBUTING.md b/.github/CONTRIBUTING.md index 9939045ac..a60662385 100644 --- a/.github/CONTRIBUTING.md +++ b/.github/CONTRIBUTING.md @@ -24,4 +24,4 @@ It is recommended that developers use a [vscode devcontainer](https://code.visua This project was created using the [Diamond Light Source Copier Template](https://github.com/DiamondLightSource/python-copier-template) for Python projects. -For more information on common tasks like setting up a developer environment, running the tests, and setting a pre-commit hook, see the template's [How-to guides](https://diamondlightsource.github.io/python-copier-template/4.1.0/how-to.html). +For more information on common tasks like setting up a developer environment, running the tests, and setting a pre-commit hook, see the template's [How-to guides](https://diamondlightsource.github.io/python-copier-template/4.3.0/how-to.html). diff --git a/docs/reference/asyncapi.yaml b/docs/reference/asyncapi.yaml index f78394420..0c711c61b 100644 --- a/docs/reference/asyncapi.yaml +++ b/docs/reference/asyncapi.yaml @@ -5,8 +5,8 @@ info: version: 0.0.2 description: Service for controlling access to and running scans based on Bluesky Plans and Ophyd Devices contact: - name: Callum Forrester - email: callum.forrester@diamond.ac.uk + name: Abigail Emery + email: abigail.emery@diamond.ac.uk license: name: Apache 2.0 url: https://www.apache.org/licenses/LICENSE-2.0.html diff --git a/pyproject.toml b/pyproject.toml index 2efe588f5..c1771e2ec 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -78,8 +78,8 @@ blueapi = "blueapi.cli:main" GitHub = "https://github.com/DiamondLightSource/blueapi" [[project.authors]] # Further authors may be added by duplicating this section -email = "callum.forrester@diamond.ac.uk" -name = "Callum Forrester" +email = "abigail.emery@diamond.ac.uk" +name = "Abigail Emery" [tool.setuptools_scm] @@ -102,6 +102,7 @@ testpaths = "docs src tests" asyncio_mode = "auto" [tool.coverage.run] +patch = ["subprocess"] data_file = "/tmp/blueapi.coverage" omit = ["src/blueapi/startup/**/*"] @@ -142,6 +143,7 @@ lint.select = [ "C4", # flake8-comprehensions - https://docs.astral.sh/ruff/rules/#flake8-comprehensions-c4 "E", # pycodestyle errors - https://docs.astral.sh/ruff/rules/#error-e "F", # pyflakes rules - https://docs.astral.sh/ruff/rules/#pyflakes-f + "N", # pep8-naming - https://docs.astral.sh/ruff/rules/#pep8-naming-n "W", # pycodestyle warnings - https://docs.astral.sh/ruff/rules/#warning-w "I", # isort - https://docs.astral.sh/ruff/rules/#isort-i "UP", # pyupgrade - https://docs.astral.sh/ruff/rules/#pyupgrade-up From 351505be534f4b825895c2cf541b76ef00c9b2bb Mon Sep 17 00:00:00 2001 From: Joseph Ware <53935796+DiamondJoseph@users.noreply.github.com> Date: Mon, 27 Oct 2025 14:35:51 +0000 Subject: [PATCH 02/11] N803 Argument name should be lowercase --- src/blueapi/utils/connect_devices.py | 4 +- tests/conftest.py | 12 +- tests/unit_tests/core/test_context.py | 8 +- tests/unit_tests/service/test_rest_api.py | 3 +- tests/unit_tests/test_helm_chart.py | 301 ++++++++++---------- tests/unit_tests/worker/test_task_worker.py | 2 +- 6 files changed, 166 insertions(+), 164 deletions(-) diff --git a/src/blueapi/utils/connect_devices.py b/src/blueapi/utils/connect_devices.py index 863d77017..756fab3fa 100644 --- a/src/blueapi/utils/connect_devices.py +++ b/src/blueapi/utils/connect_devices.py @@ -29,7 +29,7 @@ def _report_successful_devices( def _establish_device_connections( - RE: RunEngine, + run_engine: RunEngine, devices: Mapping[str, AnyDevice], sim_backend: bool, ) -> tuple[Mapping[str, AnyDevice], Mapping[str, Exception]]: @@ -45,7 +45,7 @@ def _establish_device_connections( # Connect ophyd-async devices try: - RE(ensure_connected(*ophyd_async_devices.values(), mock=sim_backend)) + run_engine(ensure_connected(*ophyd_async_devices.values(), mock=sim_backend)) except NotConnected as ex: exceptions = {**exceptions, **ex.sub_errors} diff --git a/tests/conftest.py b/tests/conftest.py index 1772ab242..b2f7cb947 100644 --- a/tests/conftest.py +++ b/tests/conftest.py @@ -27,23 +27,23 @@ @pytest.fixture(scope="function") -def RE(request): +def run_engine(request): loop = asyncio.new_event_loop() loop.set_debug(True) - RE = RunEngine({}, call_returns_result=True, loop=loop) + run_engine = RunEngine({}, call_returns_result=True, loop=loop) def clean_event_loop(): - if RE.state not in ("idle", "panicked"): + if run_engine.state not in ("idle", "panicked"): try: - RE.halt() + run_engine.halt() except TransitionError: pass loop.call_soon_threadsafe(loop.stop) - RE._th.join() + run_engine._th.join() loop.close() request.addfinalizer(clean_event_loop) - return RE + return run_engine @pytest.fixture(scope="session") diff --git a/tests/unit_tests/core/test_context.py b/tests/unit_tests/core/test_context.py index 3a4166d5b..2e3bdcee6 100644 --- a/tests/unit_tests/core/test_context.py +++ b/tests/unit_tests/core/test_context.py @@ -106,14 +106,14 @@ def has_default_nested_reference( @pytest.fixture -def sim_motor(RE: RunEngine) -> Motor: +def sim_motor(run_engine: RunEngine) -> Motor: with init_devices(mock=True): sim = Motor("FOO:") return sim @pytest.fixture -def alt_motor(RE: RunEngine) -> Motor: +def alt_motor(run_engine: RunEngine) -> Motor: with init_devices(mock=True): alt = Motor("BAR:") return alt @@ -298,8 +298,8 @@ def test_extra_kwargs_in_with_dodal_module_passed_to_make_all_devices( def test_with_dodal_module_returns_connection_exceptions(empty_context: BlueskyContext): import tests.unit_tests.core.fake_device_module as device_module - def connect_sim_backend(RE, devices, sim_backend): - return _establish_device_connections(RE, devices, True) + def connect_sim_backend(run_engine: RunEngine, devices, sim_backend): + return _establish_device_connections(run_engine, devices, True) with patch( "blueapi.utils.connect_devices._establish_device_connections", diff --git a/tests/unit_tests/service/test_rest_api.py b/tests/unit_tests/service/test_rest_api.py index b990ea3c2..0c731723f 100644 --- a/tests/unit_tests/service/test_rest_api.py +++ b/tests/unit_tests/service/test_rest_api.py @@ -129,13 +129,12 @@ def test_rest_config_with_cors( ) task_id = "f8424be3-203c-494e-b22f-219933b4fa67" mock_runner.run.side_effect = [task_id] - HEADERS = {"Accept": "application/json", "Content-Type": "application/json"} # Allowed method response_post = client_with_cors.post( "/tasks", json=task.model_dump(), - headers=HEADERS, + headers={"Accept": "application/json", "Content-Type": "application/json"}, ) assert response_post.status_code == status.HTTP_201_CREATED assert response_post.headers["content-type"] == "application/json" diff --git a/tests/unit_tests/test_helm_chart.py b/tests/unit_tests/test_helm_chart.py index d1b3c882f..3cd1b7a84 100644 --- a/tests/unit_tests/test_helm_chart.py +++ b/tests/unit_tests/test_helm_chart.py @@ -391,7 +391,10 @@ def test_fluentd_ignore_false_when_graylog_disabled(): def render_persistent_volume_chart( - init_container_enabled, persistentVolume_enabled, existingClaimName, debug_enabled + init_container_enabled, + persistent_volume_enabled, + existing_claim_name, + debug_enabled, ): """Generated chart for this section of Values: ``` @@ -399,7 +402,7 @@ def render_persistent_volume_chart( enabled: false persistentVolume: enabled: true - # existingClaimName: foo + # existing_claim_name: foo debug: enabled: false @@ -410,11 +413,11 @@ def render_persistent_volume_chart( "initContainer": { "enabled": init_container_enabled, "persistentVolume": { - "enabled": persistentVolume_enabled, + "enabled": persistent_volume_enabled, } | ( - {"existingClaimName": existingClaimName} - if existingClaimName + {"existing_claim_name": existing_claim_name} + if existing_claim_name else {} ), }, @@ -497,20 +500,20 @@ def test_init_container_exists_conditions(init_container_enabled): assert "initContainers" not in manifests["StatefulSet"]["blueapi"]["spec"] -@pytest.mark.parametrize("persistentVolume_enabled", [True, False]) -@pytest.mark.parametrize("existingClaimName", [None, "foo"]) +@pytest.mark.parametrize("persistent_volume_enabled", [True, False]) +@pytest.mark.parametrize("existing_claim_name", [None, "foo"]) @pytest.mark.parametrize("debug_enabled", [True, False]) def test_init_container_scratch_mount( - persistentVolume_enabled, - existingClaimName, + persistent_volume_enabled, + existing_claim_name, debug_enabled, scratch_volume_mount, scratch_host_volume_mount, ): manifests = render_persistent_volume_chart( True, - persistentVolume_enabled, - existingClaimName, + persistent_volume_enabled, + existing_claim_name, debug_enabled, ) @@ -518,7 +521,7 @@ def test_init_container_scratch_mount( "initContainers" ][0]["volumeMounts"] - if persistentVolume_enabled: + if persistent_volume_enabled: assert scratch_volume_mount in volume_mounts assert not any(mount["name"] == "scratch-host" for mount in volume_mounts) else: @@ -526,19 +529,19 @@ def test_init_container_scratch_mount( assert not any(mount["name"] == "scratch" for mount in volume_mounts) -@pytest.mark.parametrize("persistentVolume_enabled", [True, False]) -@pytest.mark.parametrize("existingClaimName", [None, "foo"]) +@pytest.mark.parametrize("persistent_volume_enabled", [True, False]) +@pytest.mark.parametrize("existing_claim_name", [None, "foo"]) @pytest.mark.parametrize("debug_enabled", [True, False]) def test_init_container_init_config_mount( - persistentVolume_enabled, - existingClaimName, + persistent_volume_enabled, + existing_claim_name, debug_enabled, init_config_volume_mount, ): manifests = render_persistent_volume_chart( True, - persistentVolume_enabled, - existingClaimName, + persistent_volume_enabled, + existing_claim_name, debug_enabled, ) @@ -549,19 +552,19 @@ def test_init_container_init_config_mount( assert init_config_volume_mount in volume_mounts -@pytest.mark.parametrize("persistentVolume_enabled", [True, False]) -@pytest.mark.parametrize("existingClaimName", [None, "foo"]) +@pytest.mark.parametrize("persistent_volume_enabled", [True, False]) +@pytest.mark.parametrize("existing_claim_name", [None, "foo"]) @pytest.mark.parametrize("debug_enabled", [True, False]) def test_init_container_venv_volume_mount( - persistentVolume_enabled, - existingClaimName, + persistent_volume_enabled, + existing_claim_name, debug_enabled, init_container_venv_volume_mount, ): manifests = render_persistent_volume_chart( True, - persistentVolume_enabled, - existingClaimName, + persistent_volume_enabled, + existing_claim_name, debug_enabled, ) @@ -572,20 +575,20 @@ def test_init_container_venv_volume_mount( assert init_container_venv_volume_mount in volume_mounts -@pytest.mark.parametrize("initContainer_enabled", [True, False]) -@pytest.mark.parametrize("persistentVolume_enabled", [True, False]) -@pytest.mark.parametrize("existingClaimName", [None, "foo"]) +@pytest.mark.parametrize("init_container_enabled", [True, False]) +@pytest.mark.parametrize("persistent_volume_enabled", [True, False]) +@pytest.mark.parametrize("existing_claim_name", [None, "foo"]) @pytest.mark.parametrize("debug_enabled", [True, False]) def test_persistent_volume_claim_exists( - initContainer_enabled, - persistentVolume_enabled, - existingClaimName, + init_container_enabled, + persistent_volume_enabled, + existing_claim_name, debug_enabled, ): manifests = render_persistent_volume_chart( - initContainer_enabled, - persistentVolume_enabled, - existingClaimName, + init_container_enabled, + persistent_volume_enabled, + existing_claim_name, debug_enabled, ) @@ -604,30 +607,30 @@ def test_persistent_volume_claim_exists( } } - if persistentVolume_enabled and not existingClaimName: + if persistent_volume_enabled and not existing_claim_name: assert persistent_volume_claim == manifests["PersistentVolumeClaim"] else: assert "PersistentVolumeClaim" not in manifests -@pytest.mark.parametrize("initContainer_enabled", [True, False]) -@pytest.mark.parametrize("persistentVolume_enabled", [True, False]) -@pytest.mark.parametrize("existingClaimName", [None, "foo"]) +@pytest.mark.parametrize("init_container_enabled", [True, False]) +@pytest.mark.parametrize("persistent_volume_enabled", [True, False]) +@pytest.mark.parametrize("existing_claim_name", [None, "foo"]) @pytest.mark.parametrize("debug_enabled", [True, False]) def test_debug_account_sync_exists( - initContainer_enabled, - persistentVolume_enabled, - existingClaimName, + init_container_enabled, + persistent_volume_enabled, + existing_claim_name, debug_enabled, ): manifests = render_persistent_volume_chart( - initContainer_enabled, - persistentVolume_enabled, - existingClaimName, + init_container_enabled, + persistent_volume_enabled, + existing_claim_name, debug_enabled, ) - if debug_enabled or (initContainer_enabled and persistentVolume_enabled): + if debug_enabled or (init_container_enabled and persistent_volume_enabled): assert { "name": "debug-account-sync", "image": ANY, @@ -647,20 +650,20 @@ def test_debug_account_sync_exists( ) -@pytest.mark.parametrize("initContainer_enabled", [True, False]) -@pytest.mark.parametrize("persistentVolume_enabled", [True, False]) -@pytest.mark.parametrize("existingClaimName", [None, "foo"]) +@pytest.mark.parametrize("init_container_enabled", [True, False]) +@pytest.mark.parametrize("persistent_volume_enabled", [True, False]) +@pytest.mark.parametrize("existing_claim_name", [None, "foo"]) @pytest.mark.parametrize("debug_enabled", [True, False]) def test_container_image_has_debug_suffix( - initContainer_enabled, - persistentVolume_enabled, - existingClaimName, + init_container_enabled, + persistent_volume_enabled, + existing_claim_name, debug_enabled, ): manifests = render_persistent_volume_chart( - initContainer_enabled, - persistentVolume_enabled, - existingClaimName, + init_container_enabled, + persistent_volume_enabled, + existing_claim_name, debug_enabled, ) @@ -676,29 +679,29 @@ def test_container_image_has_debug_suffix( ][0]["image"] assert not str(image).endswith("-debug") - if initContainer_enabled: + if init_container_enabled: init_image = manifests["StatefulSet"]["blueapi"]["spec"]["template"]["spec"][ "initContainers" ][0]["image"] assert init_image == image -@pytest.mark.parametrize("initContainer_enabled", [True, False]) -@pytest.mark.parametrize("persistentVolume_enabled", [True, False]) -@pytest.mark.parametrize("existingClaimName", [None, "foo"]) +@pytest.mark.parametrize("init_container_enabled", [True, False]) +@pytest.mark.parametrize("persistent_volume_enabled", [True, False]) +@pytest.mark.parametrize("existing_claim_name", [None, "foo"]) @pytest.mark.parametrize("debug_enabled", [True, False]) def test_main_container_scratch_mount( - initContainer_enabled, - persistentVolume_enabled, - existingClaimName, + init_container_enabled, + persistent_volume_enabled, + existing_claim_name, debug_enabled, scratch_volume_mount, scratch_host_volume_mount, ): manifests = render_persistent_volume_chart( - initContainer_enabled, - persistentVolume_enabled, - existingClaimName, + init_container_enabled, + persistent_volume_enabled, + existing_claim_name, debug_enabled, ) @@ -706,10 +709,10 @@ def test_main_container_scratch_mount( "containers" ][0]["volumeMounts"] - if initContainer_enabled and persistentVolume_enabled: + if init_container_enabled and persistent_volume_enabled: assert scratch_volume_mount in volume_mounts assert not any(mount["name"] == "scratch-host" for mount in volume_mounts) - elif initContainer_enabled: + elif init_container_enabled: assert scratch_host_volume_mount in volume_mounts assert not any(mount["name"] == "scratch" for mount in volume_mounts) else: @@ -717,21 +720,21 @@ def test_main_container_scratch_mount( assert not any(mount["name"] == "scratch" for mount in volume_mounts) -@pytest.mark.parametrize("initContainer_enabled", [True, False]) -@pytest.mark.parametrize("persistentVolume_enabled", [True, False]) -@pytest.mark.parametrize("existingClaimName", [None, "foo"]) +@pytest.mark.parametrize("init_container_enabled", [True, False]) +@pytest.mark.parametrize("persistent_volume_enabled", [True, False]) +@pytest.mark.parametrize("existing_claim_name", [None, "foo"]) @pytest.mark.parametrize("debug_enabled", [True, False]) def test_main_container_venv_volume_mount( - initContainer_enabled, - persistentVolume_enabled, - existingClaimName, + init_container_enabled, + persistent_volume_enabled, + existing_claim_name, debug_enabled, venv_volume_mount, ): manifests = render_persistent_volume_chart( - initContainer_enabled, - persistentVolume_enabled, - existingClaimName, + init_container_enabled, + persistent_volume_enabled, + existing_claim_name, debug_enabled, ) @@ -739,28 +742,28 @@ def test_main_container_venv_volume_mount( "containers" ][0]["volumeMounts"] - if initContainer_enabled: + if init_container_enabled: assert venv_volume_mount in volume_mounts else: assert venv_volume_mount not in volume_mounts -@pytest.mark.parametrize("initContainer_enabled", [True, False]) -@pytest.mark.parametrize("persistentVolume_enabled", [True, False]) -@pytest.mark.parametrize("existingClaimName", [None, "foo"]) +@pytest.mark.parametrize("init_container_enabled", [True, False]) +@pytest.mark.parametrize("persistent_volume_enabled", [True, False]) +@pytest.mark.parametrize("existing_claim_name", [None, "foo"]) @pytest.mark.parametrize("debug_enabled", [True, False]) def test_main_container_home_and_nslcd_volume_mounts( - initContainer_enabled, - persistentVolume_enabled, - existingClaimName, + init_container_enabled, + persistent_volume_enabled, + existing_claim_name, debug_enabled, home_volume_mount, nslcd_volume_mount, ): manifests = render_persistent_volume_chart( - initContainer_enabled, - persistentVolume_enabled, - existingClaimName, + init_container_enabled, + persistent_volume_enabled, + existing_claim_name, debug_enabled, ) @@ -768,7 +771,7 @@ def test_main_container_home_and_nslcd_volume_mounts( "containers" ][0]["volumeMounts"] - if debug_enabled or (initContainer_enabled and persistentVolume_enabled): + if debug_enabled or (init_container_enabled and persistent_volume_enabled): assert home_volume_mount in volume_mounts assert nslcd_volume_mount in volume_mounts else: @@ -776,22 +779,22 @@ def test_main_container_home_and_nslcd_volume_mounts( assert nslcd_volume_mount not in volume_mounts -@pytest.mark.parametrize("initContainer_enabled", [True, False]) -@pytest.mark.parametrize("persistentVolume_enabled", [True, False]) -@pytest.mark.parametrize("existingClaimName", [None, "foo"]) +@pytest.mark.parametrize("init_container_enabled", [True, False]) +@pytest.mark.parametrize("persistent_volume_enabled", [True, False]) +@pytest.mark.parametrize("existing_claim_name", [None, "foo"]) @pytest.mark.parametrize("debug_enabled", [True, False]) def test_main_container_args( - initContainer_enabled, - persistentVolume_enabled, - existingClaimName, + init_container_enabled, + persistent_volume_enabled, + existing_claim_name, debug_enabled, home_volume_mount, nslcd_volume_mount, ): manifests = render_persistent_volume_chart( - initContainer_enabled, - persistentVolume_enabled, - existingClaimName, + init_container_enabled, + persistent_volume_enabled, + existing_claim_name, debug_enabled, ) @@ -812,16 +815,16 @@ def test_main_container_args( ) -@pytest.mark.parametrize("existingClaimName", [None, "foo"]) +@pytest.mark.parametrize("existing_claim_name", [None, "foo"]) @pytest.mark.parametrize("debug_enabled", [True, False]) -def test_scratch_volume_uses_correct_claimName( - existingClaimName, +def test_scratch_volume_uses_correct_name( + existing_claim_name, debug_enabled, ): manifests = render_persistent_volume_chart( True, True, - existingClaimName, + existing_claim_name, debug_enabled, ) @@ -829,8 +832,8 @@ def test_scratch_volume_uses_correct_claimName( "volumes" ][3]["persistentVolumeClaim"]["claimName"] - if existingClaimName: - assert claim_name == existingClaimName + if existing_claim_name: + assert claim_name == existing_claim_name assert "PersistentVolumeClaim" not in manifests else: assert claim_name == "scratch-0.1.0" @@ -878,21 +881,21 @@ def nslcd_volume(): return {"name": "nslcd", "emptyDir": {"sizeLimit": "5Mi"}} -@pytest.mark.parametrize("initContainer_enabled", [True, False]) -@pytest.mark.parametrize("persistentVolume_enabled", [True, False]) -@pytest.mark.parametrize("existingClaimName", [None, "foo"]) +@pytest.mark.parametrize("init_container_enabled", [True, False]) +@pytest.mark.parametrize("persistent_volume_enabled", [True, False]) +@pytest.mark.parametrize("existing_claim_name", [None, "foo"]) @pytest.mark.parametrize("debug_enabled", [True, False]) def test_worker_config_volume_declared( - initContainer_enabled, - persistentVolume_enabled, - existingClaimName, + init_container_enabled, + persistent_volume_enabled, + existing_claim_name, debug_enabled, worker_config_volume, ): manifests = render_persistent_volume_chart( - initContainer_enabled, - persistentVolume_enabled, - existingClaimName, + init_container_enabled, + persistent_volume_enabled, + existing_claim_name, debug_enabled, ) @@ -902,26 +905,26 @@ def test_worker_config_volume_declared( ) -@pytest.mark.parametrize("initContainer_enabled", [True, False]) -@pytest.mark.parametrize("persistentVolume_enabled", [True, False]) -@pytest.mark.parametrize("existingClaimName", [None, "foo"]) +@pytest.mark.parametrize("init_container_enabled", [True, False]) +@pytest.mark.parametrize("persistent_volume_enabled", [True, False]) +@pytest.mark.parametrize("existing_claim_name", [None, "foo"]) @pytest.mark.parametrize("debug_enabled", [True, False]) def test_init_config_and_venv_volumes_declared( - initContainer_enabled, - persistentVolume_enabled, - existingClaimName, + init_container_enabled, + persistent_volume_enabled, + existing_claim_name, debug_enabled, init_config_volume, venv_volume, ): manifests = render_persistent_volume_chart( - initContainer_enabled, - persistentVolume_enabled, - existingClaimName, + init_container_enabled, + persistent_volume_enabled, + existing_claim_name, debug_enabled, ) - if initContainer_enabled: + if init_container_enabled: assert ( init_config_volume in manifests["StatefulSet"]["blueapi"]["spec"]["template"]["spec"][ @@ -950,25 +953,25 @@ def test_init_config_and_venv_volumes_declared( ) -@pytest.mark.parametrize("initContainer_enabled", [True, False]) -@pytest.mark.parametrize("persistentVolume_enabled", [True, False]) -@pytest.mark.parametrize("existingClaimName", [None, "foo"]) +@pytest.mark.parametrize("init_container_enabled", [True, False]) +@pytest.mark.parametrize("persistent_volume_enabled", [True, False]) +@pytest.mark.parametrize("existing_claim_name", [None, "foo"]) @pytest.mark.parametrize("debug_enabled", [True, False]) def test_scratch_volume_declared( - initContainer_enabled, - persistentVolume_enabled, - existingClaimName, + init_container_enabled, + persistent_volume_enabled, + existing_claim_name, debug_enabled, scratch_volume, ): manifests = render_persistent_volume_chart( - initContainer_enabled, - persistentVolume_enabled, - existingClaimName, + init_container_enabled, + persistent_volume_enabled, + existing_claim_name, debug_enabled, ) - if initContainer_enabled and persistentVolume_enabled: + if init_container_enabled and persistent_volume_enabled: assert ( scratch_volume in manifests["StatefulSet"]["blueapi"]["spec"]["template"]["spec"][ @@ -984,25 +987,25 @@ def test_scratch_volume_declared( ) -@pytest.mark.parametrize("initContainer_enabled", [True, False]) -@pytest.mark.parametrize("persistentVolume_enabled", [True, False]) -@pytest.mark.parametrize("existingClaimName", [None, "foo"]) +@pytest.mark.parametrize("init_container_enabled", [True, False]) +@pytest.mark.parametrize("persistent_volume_enabled", [True, False]) +@pytest.mark.parametrize("existing_claim_name", [None, "foo"]) @pytest.mark.parametrize("debug_enabled", [True, False]) def test_scratch_host_volume_declared( - initContainer_enabled, - persistentVolume_enabled, - existingClaimName, + init_container_enabled, + persistent_volume_enabled, + existing_claim_name, debug_enabled, scratch_host_volume, ): manifests = render_persistent_volume_chart( - initContainer_enabled, - persistentVolume_enabled, - existingClaimName, + init_container_enabled, + persistent_volume_enabled, + existing_claim_name, debug_enabled, ) - if initContainer_enabled and not persistentVolume_enabled: + if init_container_enabled and not persistent_volume_enabled: assert ( scratch_host_volume in manifests["StatefulSet"]["blueapi"]["spec"]["template"]["spec"][ @@ -1018,26 +1021,26 @@ def test_scratch_host_volume_declared( ) -@pytest.mark.parametrize("initContainer_enabled", [True, False]) -@pytest.mark.parametrize("persistentVolume_enabled", [True, False]) -@pytest.mark.parametrize("existingClaimName", [None, "foo"]) +@pytest.mark.parametrize("init_container_enabled", [True, False]) +@pytest.mark.parametrize("persistent_volume_enabled", [True, False]) +@pytest.mark.parametrize("existing_claim_name", [None, "foo"]) @pytest.mark.parametrize("debug_enabled", [True, False]) def test_home_and_nslcd_volumes_declared( - initContainer_enabled, - persistentVolume_enabled, - existingClaimName, + init_container_enabled, + persistent_volume_enabled, + existing_claim_name, debug_enabled, home_volume, nslcd_volume, ): manifests = render_persistent_volume_chart( - initContainer_enabled, - persistentVolume_enabled, - existingClaimName, + init_container_enabled, + persistent_volume_enabled, + existing_claim_name, debug_enabled, ) - if debug_enabled or (initContainer_enabled and persistentVolume_enabled): + if debug_enabled or (init_container_enabled and persistent_volume_enabled): assert ( home_volume in manifests["StatefulSet"]["blueapi"]["spec"]["template"]["spec"][ diff --git a/tests/unit_tests/worker/test_task_worker.py b/tests/unit_tests/worker/test_task_worker.py index e66323dc5..99c43f112 100644 --- a/tests/unit_tests/worker/test_task_worker.py +++ b/tests/unit_tests/worker/test_task_worker.py @@ -339,7 +339,7 @@ def _sleep_events(task_id: str) -> list[WorkerEvent]: @patch("queue.Queue.put_nowait") -def test_full_queue_raises_WorkerBusyError(put_nowait: MagicMock, worker: TaskWorker): +def test_full_queue_raises(put_nowait: MagicMock, worker: TaskWorker): def raise_full(item): raise Full() From 4a36988ff9307179e27a12b88fbd0b4d612ee6b8 Mon Sep 17 00:00:00 2001 From: Joseph Ware <53935796+DiamondJoseph@users.noreply.github.com> Date: Mon, 27 Oct 2025 14:36:57 +0000 Subject: [PATCH 03/11] N818 Exception should be named with an Error suffix --- src/blueapi/cli/cli.py | 16 ++++++++-------- src/blueapi/client/client.py | 4 ++-- src/blueapi/client/rest.py | 18 +++++++++--------- src/blueapi/config.py | 2 +- tests/system_tests/test_blueapi_system.py | 4 ++-- tests/unit_tests/client/test_client.py | 6 +++--- tests/unit_tests/client/test_rest.py | 14 +++++++------- tests/unit_tests/test_cli.py | 12 ++++++------ 8 files changed, 38 insertions(+), 38 deletions(-) diff --git a/src/blueapi/cli/cli.py b/src/blueapi/cli/cli.py index 6468e2cca..957a9cb27 100644 --- a/src/blueapi/cli/cli.py +++ b/src/blueapi/cli/cli.py @@ -25,9 +25,9 @@ from blueapi.client.event_bus import AnyEvent, BlueskyStreamingError, EventBusClient from blueapi.client.rest import ( BlueskyRemoteControlError, - InvalidParameters, - UnauthorisedAccess, - UnknownPlan, + InvalidParametersError, + UnauthorisedAccessError, + UnknownPlanError, ) from blueapi.config import ( ApplicationConfig, @@ -303,7 +303,7 @@ def run_plan( instrument_session=instrument_session, ) except ValidationError as ve: - ip = InvalidParameters.from_validation_error(ve) + ip = InvalidParametersError.from_validation_error(ve) raise ClickException(ip.message()) from ip try: @@ -324,13 +324,13 @@ def on_event(event: AnyEvent) -> None: else: server_task = client.create_and_start_task(task) click.echo(server_task.task_id) - except config.MissingStompConfiguration as mse: + except config.MissingStompConfigurationError as mse: raise ClickException(*mse.args) from mse - except UnknownPlan as up: + except UnknownPlanError as up: raise ClickException(f"Plan '{name}' was not recognised") from up - except UnauthorisedAccess as ua: + except UnauthorisedAccessError as ua: raise ClickException("Unauthorised request") from ua - except InvalidParameters as ip: + except InvalidParametersError as ip: raise ClickException(ip.message()) from ip except (BlueskyRemoteControlError, BlueskyStreamingError) as e: raise ClickException(f"server error with this message: {e}") from e diff --git a/src/blueapi/client/client.py b/src/blueapi/client/client.py index 6dad099be..0930e240a 100644 --- a/src/blueapi/client/client.py +++ b/src/blueapi/client/client.py @@ -8,7 +8,7 @@ start_as_current_span, ) -from blueapi.config import ApplicationConfig, MissingStompConfiguration +from blueapi.config import ApplicationConfig, MissingStompConfigurationError from blueapi.core.bluesky_types import DataEvent from blueapi.service.authentication import SessionManager from blueapi.service.model import ( @@ -217,7 +217,7 @@ def run_task( """ if self._events is None: - raise MissingStompConfiguration( + raise MissingStompConfigurationError( "Stomp configuration required to run plans is missing or disabled" ) diff --git a/src/blueapi/client/rest.py b/src/blueapi/client/rest.py index a5ac1a5b7..36bf9ec5c 100644 --- a/src/blueapi/client/rest.py +++ b/src/blueapi/client/rest.py @@ -33,7 +33,7 @@ TRACER = get_tracer("rest") -class UnauthorisedAccess(Exception): +class UnauthorisedAccessError(Exception): pass @@ -46,7 +46,7 @@ def __init__(self, code: int, message: str) -> None: super().__init__(message, code) -class NoContent(Exception): +class NoContentError(Exception): """Request returned 204 (No Content): handle if None is allowed""" def __init__(self, target_type: type) -> None: @@ -74,7 +74,7 @@ def __str__(self) -> str: ) -class InvalidParameters(Exception): +class InvalidParametersError(Exception): def __init__(self, errors: list[ParameterError]): self.errors = errors @@ -96,7 +96,7 @@ def from_validation_error(cls, ve: ValidationError): ) -class UnknownPlan(Exception): +class UnknownPlanError(Exception): pass @@ -115,13 +115,13 @@ def _create_task_exceptions(response: requests.Response) -> Exception | None: if code < 400: return None elif code == 401 or code == 403: - return UnauthorisedAccess() + return UnauthorisedAccessError() elif code == 404: - return UnknownPlan() + return UnknownPlanError() elif code == 422: try: content = response.json() - return InvalidParameters( + return InvalidParametersError( TypeAdapter(list[ParameterError]).validate_python( content.get("detail", []) ) @@ -226,7 +226,7 @@ def delete_environment(self) -> EnvironmentResponse: def get_oidc_config(self) -> OIDCConfig | None: try: return self._request_and_deserialize("/config/oidc", OIDCConfig) - except NoContent: + except NoContentError: # Server is not using authentication return None @@ -264,6 +264,6 @@ def _request_and_deserialize( if exception is not None: raise exception if response.status_code == status.HTTP_204_NO_CONTENT: - raise NoContent(target_type) + raise NoContentError(target_type) deserialized = TypeAdapter(target_type).validate_python(response.json()) return deserialized diff --git a/src/blueapi/config.py b/src/blueapi/config.py index a4e01bd1a..5901d1ea2 100644 --- a/src/blueapi/config.py +++ b/src/blueapi/config.py @@ -321,5 +321,5 @@ def load(self) -> C: ) from exc -class MissingStompConfiguration(Exception): +class MissingStompConfigurationError(Exception): pass diff --git a/tests/system_tests/test_blueapi_system.py b/tests/system_tests/test_blueapi_system.py index 28e0e2150..f38653adb 100644 --- a/tests/system_tests/test_blueapi_system.py +++ b/tests/system_tests/test_blueapi_system.py @@ -15,7 +15,7 @@ BlueskyRemoteControlError, ) from blueapi.client.event_bus import AnyEvent -from blueapi.client.rest import UnknownPlan +from blueapi.client.rest import UnknownPlanError from blueapi.config import ( ApplicationConfig, ConfigLoader, @@ -253,7 +253,7 @@ def test_instrument_session_propagated(client: BlueapiClient): def test_create_task_validation_error(client: BlueapiClient): - with pytest.raises(UnknownPlan): + with pytest.raises(UnknownPlanError): client.create_task( TaskRequest( name="Not-exists", diff --git a/tests/unit_tests/client/test_client.py b/tests/unit_tests/client/test_client.py index 39aadda82..d13ccce80 100644 --- a/tests/unit_tests/client/test_client.py +++ b/tests/unit_tests/client/test_client.py @@ -12,7 +12,7 @@ from blueapi.client.client import BlueapiClient from blueapi.client.event_bus import AnyEvent, BlueskyStreamingError, EventBusClient from blueapi.client.rest import BlueapiRestClient, BlueskyRemoteControlError -from blueapi.config import MissingStompConfiguration +from blueapi.config import MissingStompConfigurationError from blueapi.core import DataEvent from blueapi.service.model import ( DeviceModel, @@ -394,7 +394,7 @@ def test_resume( def test_cannot_run_task_without_message_bus(client: BlueapiClient): with pytest.raises( - MissingStompConfiguration, + MissingStompConfigurationError, match="Stomp configuration required to run plans is missing or disabled", ): client.run_task(TaskRequest(name="foo", instrument_session="cm12345-1")) @@ -663,7 +663,7 @@ def test_cannot_run_task_span_ok( exporter: JsonObjectSpanExporter, client: BlueapiClient ): with pytest.raises( - MissingStompConfiguration, + MissingStompConfigurationError, match="Stomp configuration required to run plans is missing or disabled", ): with asserting_span_exporter(exporter, "grun_task"): diff --git a/tests/unit_tests/client/test_rest.py b/tests/unit_tests/client/test_rest.py index 808db3754..c8fce9d10 100644 --- a/tests/unit_tests/client/test_rest.py +++ b/tests/unit_tests/client/test_rest.py @@ -10,10 +10,10 @@ BlueapiRestClient, BlueskyRemoteControlError, BlueskyRequestError, - InvalidParameters, + InvalidParametersError, ParameterError, - UnauthorisedAccess, - UnknownPlan, + UnauthorisedAccessError, + UnknownPlanError, _create_task_exceptions, ) from blueapi.config import OIDCConfig @@ -63,9 +63,9 @@ def test_rest_error_code( "code,content,expected_exception", [ (200, None, None), - (401, None, UnauthorisedAccess()), - (403, None, UnauthorisedAccess()), - (404, None, UnknownPlan()), + (401, None, UnauthorisedAccessError()), + (403, None, UnauthorisedAccessError()), + (404, None, UnknownPlanError()), ( 422, """{ @@ -76,7 +76,7 @@ def test_rest_error_code( "input": {} }] }""", - InvalidParameters( + InvalidParametersError( [ ParameterError( loc=["body", "params", "foo"], diff --git a/tests/unit_tests/test_cli.py b/tests/unit_tests/test_cli.py index 93d87dd33..3c91d5b77 100644 --- a/tests/unit_tests/test_cli.py +++ b/tests/unit_tests/test_cli.py @@ -30,10 +30,10 @@ from blueapi.client.event_bus import BlueskyStreamingError from blueapi.client.rest import ( BlueskyRemoteControlError, - InvalidParameters, + InvalidParametersError, ParameterError, - UnauthorisedAccess, - UnknownPlan, + UnauthorisedAccessError, + UnknownPlanError, ) from blueapi.config import ( ApplicationConfig, @@ -646,10 +646,10 @@ def test_env_reload_server_side_error(runner: CliRunner): @pytest.mark.parametrize( "exception, error_message", [ - (UnknownPlan(), "Error: Plan 'sleep' was not recognised\n"), - (UnauthorisedAccess(), "Error: Unauthorised request\n"), + (UnknownPlanError(), "Error: Plan 'sleep' was not recognised\n"), + (UnauthorisedAccessError(), "Error: Unauthorised request\n"), ( - InvalidParameters( + InvalidParametersError( errors=[ ParameterError( loc=["body", "params", "foo"], From 44b9761e99a7645fbc4e7c0af139df339a804cbb Mon Sep 17 00:00:00 2001 From: Joseph Ware <53935796+DiamondJoseph@users.noreply.github.com> Date: Mon, 27 Oct 2025 14:38:20 +0000 Subject: [PATCH 04/11] N811 Constant should not be imported as non-constant --- tests/unit_tests/test_log.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/tests/unit_tests/test_log.py b/tests/unit_tests/test_log.py index 277468f38..b537a11ad 100644 --- a/tests/unit_tests/test_log.py +++ b/tests/unit_tests/test_log.py @@ -4,7 +4,7 @@ import pytest from bluesky.log import logger as bluesky_logger -from dodal.log import LOGGER as dodal_logger +from dodal.log import LOGGER as DODAL_LOGGER from blueapi.config import GraylogConfig, LoggingConfig from blueapi.log import PlanTagFilter, plan_tag_filter_context, set_up_logging @@ -96,7 +96,7 @@ def test_messages_are_tagged_with_instrument(logger, mock_handler_emit): # Temporarily duplicated https://github.com/bluesky/ophyd-async/issues/550 @pytest.mark.parametrize( "library_logger", - [bluesky_logger, dodal_logger, logging.getLogger("ophyd_async")], + [bluesky_logger, DODAL_LOGGER, logging.getLogger("ophyd_async")], ) def test_library_logger_intergrations(logger, library_logger, mock_handler_emit): mock_handler_emit.assert_not_called() From 77d34f0660343d0193a52b8ec5dadf57fed26661 Mon Sep 17 00:00:00 2001 From: Joseph Ware <53935796+DiamondJoseph@users.noreply.github.com> Date: Mon, 27 Oct 2025 14:47:45 +0000 Subject: [PATCH 05/11] fix values.yaml generation from test --- tests/unit_tests/test_helm_chart.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/unit_tests/test_helm_chart.py b/tests/unit_tests/test_helm_chart.py index 3cd1b7a84..912aff457 100644 --- a/tests/unit_tests/test_helm_chart.py +++ b/tests/unit_tests/test_helm_chart.py @@ -416,7 +416,7 @@ def render_persistent_volume_chart( "enabled": persistent_volume_enabled, } | ( - {"existing_claim_name": existing_claim_name} + {"existingClaimName": existing_claim_name} if existing_claim_name else {} ), From 134d7904965142d893dcb258be125ffc84c4acab Mon Sep 17 00:00:00 2001 From: Joseph Ware <53935796+DiamondJoseph@users.noreply.github.com> Date: Mon, 27 Oct 2025 14:48:58 +0000 Subject: [PATCH 06/11] Add Core team to project authors --- pyproject.toml | 19 +++++++++++++++++++ 1 file changed, 19 insertions(+) diff --git a/pyproject.toml b/pyproject.toml index c1771e2ec..56d0d9057 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -81,6 +81,25 @@ GitHub = "https://github.com/DiamondLightSource/blueapi" email = "abigail.emery@diamond.ac.uk" name = "Abigail Emery" +[[project.authors]] +email = "keith.ralphs@diamond.ac.uk" +name = "Keith Ralphs" + +[[project.authors]] +email = "daniel.fernandes@diamond.ac.uk" +name = "Daniel Fernandes" + +[[project.authors]] +email = "peter.holloway@diamond.ac.uk" +name = "Peter Holloway" + +[[project.authors]] +email = "zoheb.shaikh@diamond.ac.uk" +name = "Zoheb Shaikh" + +[[project.authors]] +email = "joseph.ware@diamond.ac.uk" +name = "Joseph Ware" [tool.setuptools_scm] version_file = "src/blueapi/_version.py" From d933da4efac4c4035f0cdc55d89bc46652e168df Mon Sep 17 00:00:00 2001 From: Joseph Ware <53935796+DiamondJoseph@users.noreply.github.com> Date: Mon, 27 Oct 2025 15:13:43 +0000 Subject: [PATCH 07/11] Revert codeownership changes --- .copier-answers.yml | 4 ++-- pyproject.toml | 24 ++---------------------- 2 files changed, 4 insertions(+), 24 deletions(-) diff --git a/.copier-answers.yml b/.copier-answers.yml index 4ffed9b3c..84fee94e0 100644 --- a/.copier-answers.yml +++ b/.copier-answers.yml @@ -1,8 +1,8 @@ # Changes here will be overwritten by Copier _commit: 4.3.0 _src_path: https://github.com/DiamondLightSource/python-copier-template -author_email: abigail.emery@diamond.ac.uk -author_name: Abigail Emery +author_email: callum.forrester@diamond.ac.uk +author_name: Callum Forrester component_lifecycle: production component_owner: group:default/data-acquisition component_type: service diff --git a/pyproject.toml b/pyproject.toml index 56d0d9057..32941929e 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -78,28 +78,8 @@ blueapi = "blueapi.cli:main" GitHub = "https://github.com/DiamondLightSource/blueapi" [[project.authors]] # Further authors may be added by duplicating this section -email = "abigail.emery@diamond.ac.uk" -name = "Abigail Emery" - -[[project.authors]] -email = "keith.ralphs@diamond.ac.uk" -name = "Keith Ralphs" - -[[project.authors]] -email = "daniel.fernandes@diamond.ac.uk" -name = "Daniel Fernandes" - -[[project.authors]] -email = "peter.holloway@diamond.ac.uk" -name = "Peter Holloway" - -[[project.authors]] -email = "zoheb.shaikh@diamond.ac.uk" -name = "Zoheb Shaikh" - -[[project.authors]] -email = "joseph.ware@diamond.ac.uk" -name = "Joseph Ware" +email = "callum.forrester@diamond.ac.uk" +name = "Callum Forrester" [tool.setuptools_scm] version_file = "src/blueapi/_version.py" From 48350d5702f9702ce0e50352cc36f29432f2a004 Mon Sep 17 00:00:00 2001 From: Joseph Ware <53935796+DiamondJoseph@users.noreply.github.com> Date: Tue, 28 Oct 2025 13:04:51 +0000 Subject: [PATCH 08/11] Revert code ownership --- docs/reference/asyncapi.yaml | 4 ++-- pyproject.toml | 1 + 2 files changed, 3 insertions(+), 2 deletions(-) diff --git a/docs/reference/asyncapi.yaml b/docs/reference/asyncapi.yaml index 0c711c61b..f78394420 100644 --- a/docs/reference/asyncapi.yaml +++ b/docs/reference/asyncapi.yaml @@ -5,8 +5,8 @@ info: version: 0.0.2 description: Service for controlling access to and running scans based on Bluesky Plans and Ophyd Devices contact: - name: Abigail Emery - email: abigail.emery@diamond.ac.uk + name: Callum Forrester + email: callum.forrester@diamond.ac.uk license: name: Apache 2.0 url: https://www.apache.org/licenses/LICENSE-2.0.html diff --git a/pyproject.toml b/pyproject.toml index 32941929e..8fbafcb27 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -81,6 +81,7 @@ GitHub = "https://github.com/DiamondLightSource/blueapi" email = "callum.forrester@diamond.ac.uk" name = "Callum Forrester" + [tool.setuptools_scm] version_file = "src/blueapi/_version.py" From 2a8f162eaadeff2171d255c4dbd3fbc212205021 Mon Sep 17 00:00:00 2001 From: Joseph Ware <53935796+DiamondJoseph@users.noreply.github.com> Date: Tue, 28 Oct 2025 13:05:04 +0000 Subject: [PATCH 09/11] Deprecate old error names --- src/blueapi/client/rest.py | 22 ++++++++++++++++++++++ src/blueapi/config.py | 19 +++++++++++++++++++ 2 files changed, 41 insertions(+) diff --git a/src/blueapi/client/rest.py b/src/blueapi/client/rest.py index 36bf9ec5c..3ff119449 100644 --- a/src/blueapi/client/rest.py +++ b/src/blueapi/client/rest.py @@ -267,3 +267,25 @@ def _request_and_deserialize( raise NoContentError(target_type) deserialized = TypeAdapter(target_type).validate_python(response.json()) return deserialized + + +# https://github.com/DiamondLightSource/blueapi/issues/1256 - remove before 2.0 +def __getattr__(name: str): + import warnings + + renames = { + "InvalidParameters": InvalidParametersError, + "NoContent": NoContentError, + "UnauthorisedAccess": UnauthorisedAccessError, + "UnknownPlan": UnknownPlanError, + } + rename = renames.get(name) + if rename is not None: + warnings.warn( + DeprecationWarning( + f"{name!r} is deprecated, use {rename.__name__!r} instead" + ), + stacklevel=2, + ) + return rename + raise AttributeError(f"module {__name__!r} has no attribute {name!r}") diff --git a/src/blueapi/config.py b/src/blueapi/config.py index 5901d1ea2..fce3f4d60 100644 --- a/src/blueapi/config.py +++ b/src/blueapi/config.py @@ -323,3 +323,22 @@ def load(self) -> C: class MissingStompConfigurationError(Exception): pass + + +# https://github.com/DiamondLightSource/blueapi/issues/1256 - remove before 2.0 +def __getattr__(name: str): + import warnings + + renames = { + "MissingStompConfiguration": MissingStompConfigurationError, + } + rename = renames.get(name) + if rename is not None: + warnings.warn( + DeprecationWarning( + f"{name!r} is deprecated, use {rename.__name__!r} instead" + ), + stacklevel=2, + ) + return rename + raise AttributeError(f"module {__name__!r} has no attribute {name!r}") From b4eaa8f46bf27debaa7c8b5c7561d8fc4c309061 Mon Sep 17 00:00:00 2001 From: Joseph Ware <53935796+DiamondJoseph@users.noreply.github.com> Date: Tue, 28 Oct 2025 13:07:36 +0000 Subject: [PATCH 10/11] Correct test docstring --- tests/unit_tests/test_helm_chart.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/unit_tests/test_helm_chart.py b/tests/unit_tests/test_helm_chart.py index 912aff457..2ed3a9b8c 100644 --- a/tests/unit_tests/test_helm_chart.py +++ b/tests/unit_tests/test_helm_chart.py @@ -402,7 +402,7 @@ def render_persistent_volume_chart( enabled: false persistentVolume: enabled: true - # existing_claim_name: foo + # existingClaimName: foo debug: enabled: false From 220ed5bbf7a7aee9e7bb922b8a975f497bf65d7b Mon Sep 17 00:00:00 2001 From: Joseph Ware <53935796+DiamondJoseph@users.noreply.github.com> Date: Tue, 28 Oct 2025 16:33:17 +0000 Subject: [PATCH 11/11] Add tests for deprecated exception names --- tests/unit_tests/test_deprecation.py | 31 ++++++++++++++++++++++++++++ 1 file changed, 31 insertions(+) create mode 100644 tests/unit_tests/test_deprecation.py diff --git a/tests/unit_tests/test_deprecation.py b/tests/unit_tests/test_deprecation.py new file mode 100644 index 000000000..b3418f788 --- /dev/null +++ b/tests/unit_tests/test_deprecation.py @@ -0,0 +1,31 @@ +import pytest + + +# https://github.com/DiamondLightSource/blueapi/issues/1256 +def test_invalid_parameters_deprecated(): + with pytest.deprecated_call(): + from blueapi.client.rest import InvalidParameters # noqa + + +# https://github.com/DiamondLightSource/blueapi/issues/1256 +def test_no_content_deprecated(): + with pytest.deprecated_call(): + from blueapi.client.rest import NoContent # noqa + + +# https://github.com/DiamondLightSource/blueapi/issues/1256 +def test_unauthorised_access_deprecated(): + with pytest.deprecated_call(): + from blueapi.client.rest import UnauthorisedAccess # noqa + + +# https://github.com/DiamondLightSource/blueapi/issues/1256 +def test_unknown_plan_deprecated(): + with pytest.deprecated_call(): + from blueapi.client.rest import UnknownPlan # noqa + + +# https://github.com/DiamondLightSource/blueapi/issues/1256 +def test_missing_stomp_deprecated(): + with pytest.deprecated_call(): + from blueapi.config import MissingStompConfiguration # noqa