22from unittest .mock import call
33
44import bluesky .plan_stubs as bps
5+ import numpy as np
56import pytest
67import yaml
78
89from ophyd_async .core import Settings , YamlSettingsProvider
910from ophyd_async .plan_stubs import (
1011 apply_settings ,
1112 apply_settings_if_different ,
13+ get_current_config_settings ,
1214 get_current_settings ,
15+ retrieve_config_settings ,
1316 retrieve_settings ,
1417 store_config_settings ,
1518 store_settings ,
@@ -31,6 +34,13 @@ async def parent_device() -> ParentOfEverythingDevice:
3134 return device
3235
3336
37+ @pytest .fixture
38+ async def every_parent_device () -> OneOfEverythingDevice :
39+ device = OneOfEverythingDevice ("parent" )
40+ await device .connect (mock = True )
41+ return device
42+
43+
3444async def test_get_current_settings (RE , parent_device : ParentOfEverythingDevice ):
3545 expected_values = await parent_device .get_signal_values ()
3646
@@ -41,6 +51,23 @@ def my_plan():
4151 RE (my_plan ())
4252
4353
54+ async def test_get_current_config_settings (
55+ RE , every_parent_device : OneOfEverythingDevice
56+ ):
57+ expected_values = await every_parent_device .get_signal_values ()
58+
59+ def my_plan ():
60+ current_settings = yield from get_current_config_settings (every_parent_device )
61+ current_settings = dict (current_settings )
62+ for key , value in current_settings .items ():
63+ if isinstance (value , np .ndarray ):
64+ assert np .array_equal (value , expected_values [key ])
65+ else :
66+ assert value == expected_values [key ]
67+
68+ RE (my_plan ())
69+
70+
4471async def test_store_settings (RE , parent_device : ParentOfEverythingDevice , tmp_path ):
4572 provider = YamlSettingsProvider (tmp_path )
4673
@@ -54,19 +81,16 @@ def my_plan():
5481
5582
5683async def test_store_config_settings (
57- RE , parent_device : OneOfEverythingDevice , tmp_path
84+ RE , every_parent_device : OneOfEverythingDevice , tmp_path
5885):
5986 provider = YamlSettingsProvider (tmp_path )
6087
6188 def my_plan ():
62- yield from store_config_settings (provider , "test_file" , parent_device )
89+ yield from store_config_settings (provider , "test_file" , every_parent_device )
6390 with open (tmp_path / "test_file.yaml" ) as actual_file :
6491 actual_data = yaml .safe_load (actual_file )
65- with open (TEST_DATA / "test_yaml_save .yaml" ) as expected_file :
92+ with open (TEST_DATA / "test_yaml_config_save .yaml" ) as expected_file :
6693 expected_data = yaml .safe_load (expected_file )
67- # Remove the keys that shouldn't be expected
68- expected_data .pop ("_sig_rw" , None )
69- expected_data .pop ("sig_rw" , None )
7094 assert actual_data == expected_data
7195
7296 RE (my_plan ())
@@ -108,6 +132,43 @@ def my_plan():
108132 RE (my_plan ())
109133
110134
135+ async def test_retrieve_and_apply_config_settings (
136+ RE , every_parent_device : OneOfEverythingDevice
137+ ):
138+ provider = YamlSettingsProvider (TEST_DATA )
139+ expected_values = await every_parent_device .get_signal_values ()
140+ serialized_values = {}
141+ # Override the table to be the serialized version so it compares equal
142+ for sig , value in expected_values .items ():
143+ if isinstance (value , ExampleTable ):
144+ serialized_values [sig ] = {
145+ k : pytest .approx (v ) for k , v in value .model_dump ().items ()
146+ }
147+ else :
148+ serialized_values [sig ] = pytest .approx (value )
149+
150+ def my_plan ():
151+ m = get_mock (every_parent_device )
152+ settings = yield from retrieve_config_settings (
153+ provider , "test_yaml_config_save" , every_parent_device
154+ )
155+ assert dict (settings ) == serialized_values
156+ assert not m .mock_calls
157+ yield from apply_settings (settings )
158+ assert len (m .mock_calls ) == 19
159+ m .reset_mock ()
160+ assert not m .mock_calls
161+ yield from apply_settings_if_different (settings , apply_settings )
162+ assert not m .mock_calls
163+ yield from bps .abs_set (every_parent_device .a_str , "foo" , wait = True )
164+ assert m .mock_calls == [call .a_str .put ("foo" , wait = True )]
165+ m .reset_mock ()
166+ yield from apply_settings_if_different (settings , apply_settings )
167+ assert m .mock_calls == [call .a_str .put ("test_string" , wait = True )]
168+
169+ RE (my_plan ())
170+
171+
111172async def test_ignored_settings (RE , parent_device : ParentOfEverythingDevice ):
112173 def my_plan ():
113174 m = get_mock (parent_device )
0 commit comments