44from event_model import RunStart , RunStop
55from ophyd_async .core import PathInfo
66
7- from blueapi .utils .path_provider import StartDocumentPathProvider
7+ from blueapi .utils .path_provider import (
8+ BlueskyRunStructureError ,
9+ StartDocumentPathProvider ,
10+ )
811
912
1013@pytest .fixture
@@ -217,7 +220,7 @@ def test_start_document_path_provider_run_start_called_with_different_document_s
217220 pp = StartDocumentPathProvider ()
218221 pp .run_start (name = "stop" , start_document = stop_doc_default_template ) # type: ignore
219222
220- assert pp ._doc is None
223+ assert pp ._docs == []
221224
222225
223226def test_start_document_path_provider_run_stop_called_with_different_document_skips (
@@ -226,18 +229,18 @@ def test_start_document_path_provider_run_stop_called_with_different_document_sk
226229 pp = StartDocumentPathProvider ()
227230 pp .run_stop (name = "start" , stop_document = start_doc_default_template ) # type: ignore
228231
229- assert pp ._doc is None
232+ assert pp ._docs == []
230233
231234
232235@pytest .fixture
233- def start_doc () -> dict :
236+ def start_doc_1 () -> dict :
234237 return {
235238 "uid" : "fa2feced-4098-4c0e-869d-285d2a69c24a" ,
236239 "time" : 1690463918.3893268 ,
237240 "versions" : {"ophyd" : "1.10.0" , "bluesky" : "1.13" },
238241 "data_session" : "ab123" ,
239- "instrument" : "p02 " ,
240- "data_session_directory" : "/p02 /ab123" ,
242+ "instrument" : "p01 " ,
243+ "data_session_directory" : "/p01 /ab123" ,
241244 "scan_id" : 50 ,
242245 "plan_type" : "generator" ,
243246 "plan_name" : "count" ,
@@ -257,7 +260,7 @@ def start_doc() -> dict:
257260
258261
259262@pytest .fixture
260- def stop_doc () -> dict :
263+ def stop_doc_1 () -> dict :
261264 return {
262265 "run_start" : "fa2feced-4098-4c0e-869d-285d2a69c24a" ,
263266 "time" : 1690463920.3893268 ,
@@ -268,68 +271,110 @@ def stop_doc() -> dict:
268271 }
269272
270273
271- def test_start_document_path_provider_start_doc_persists_until_stop_with_matching_id (
272- start_doc : RunStart ,
273- stop_doc : RunStop ,
274- start_doc_default_template : RunStart ,
275- stop_doc_default_template : RunStop ,
276- ):
277- pp = StartDocumentPathProvider ()
278- pp .run_start (name = "start" , start_document = start_doc )
279-
280- assert pp ._doc == start_doc
281- assert pp ._doc ["uid" ] == "fa2feced-4098-4c0e-869d-285d2a69c24a" # type: ignore
282-
283- pp .run_start (name = "start" , start_document = start_doc_default_template )
284- assert pp ._doc == start_doc
285- assert pp ._doc ["uid" ] == "fa2feced-4098-4c0e-869d-285d2a69c24a" # type: ignore
274+ @pytest .fixture
275+ def start_doc_2 () -> dict :
276+ return {
277+ "uid" : "27c48d2f-d8c6-4ac0-8146-fedf467ce11f" ,
278+ "time" : 1690463918.3893268 ,
279+ "versions" : {"ophyd" : "1.10.0" , "bluesky" : "1.13" },
280+ "data_session" : "ab123" ,
281+ "instrument" : "p02" ,
282+ "data_session_directory" : "/p02/ab123" ,
283+ "scan_id" : 51 ,
284+ "plan_type" : "generator" ,
285+ "plan_name" : "count" ,
286+ "detectors" : ["det" ],
287+ "num_points" : 1 ,
288+ "num_intervals" : 0 ,
289+ "plan_args" : {
290+ "detectors" : [
291+ "<ophyd_async.epics.adaravis._aravis.AravisDetector object at 0x7f74c02b8710>" # NOQA: E501
292+ ],
293+ "num" : 1 ,
294+ "delay" : 0.0 ,
295+ },
296+ "hints" : {"dimensions" : [[["time" ], "primary" ]]},
297+ "shape" : [1 ],
298+ }
286299
287- pp .run_stop (name = "stop" , stop_document = stop_doc_default_template )
288- assert pp ._doc == start_doc
289- assert pp ._doc ["uid" ] == "fa2feced-4098-4c0e-869d-285d2a69c24a" # type: ignore
290300
291- pp .run_stop (name = "stop" , stop_document = stop_doc )
292- assert pp ._doc is None
301+ @pytest .fixture
302+ def stop_doc_2 () -> dict :
303+ return {
304+ "run_start" : "27c48d2f-d8c6-4ac0-8146-fedf467ce11f" ,
305+ "time" : 1690463920.3893268 ,
306+ "uid" : "401ad197-5456-4a7d-ba5b-9cf8ad38d914" ,
307+ "exit_status" : "success" ,
308+ "reason" : "" ,
309+ "num_events" : {"primary" : 1 },
310+ }
293311
294312
295- def test_start_document_path_provider_nested_runs_use_parent_run_info (
296- start_doc_default_template : RunStart ,
297- stop_doc_default_template : RunStop ,
298- start_doc : RunStart ,
299- stop_doc : RunStop ,
313+ def test_start_document_path_provider_nested_runs_use_info_from_last_start_doc (
314+ start_doc_1 : RunStart ,
315+ stop_doc_1 : RunStop ,
316+ start_doc_2 : RunStart ,
317+ stop_doc_2 : RunStop ,
300318):
301319 pp = StartDocumentPathProvider ()
302- pp .run_start (name = "start" , start_document = start_doc_default_template )
303- parent_path_info = pp ("det" )
304320
305- assert pp ._doc == start_doc_default_template
306- assert pp ._doc ["uid" ] == "27c48d2f-d8c6-4ac0-8146-fedf467ce11f" # type: ignore
307- assert parent_path_info == PathInfo (
321+ pp .run_start (name = "start" , start_document = start_doc_1 )
322+ start_doc_1_path_info = PathInfo (
308323 directory_path = PosixPath ("/p01/ab123" ),
309- filename = "det-p01-22 " ,
324+ filename = "det-p01-50 " ,
310325 create_dir_depth = 0 ,
311326 )
312327
313- pp .run_start (name = "start" , start_document = start_doc )
314- assert pp ._doc == start_doc_default_template
315- assert pp ._doc ["uid" ] == "27c48d2f-d8c6-4ac0-8146-fedf467ce11f" # type: ignore
328+ assert pp ._docs [- 1 ] == start_doc_1
329+ assert pp ._docs [- 1 ]["uid" ] == "fa2feced-4098-4c0e-869d-285d2a69c24a"
330+ assert pp ("det" ) == start_doc_1_path_info
331+
332+ pp .run_start (name = "start" , start_document = start_doc_2 )
333+ start_doc_2_path_info = PathInfo (
334+ directory_path = PosixPath ("/p02/ab123" ),
335+ filename = "det-p02-51" ,
336+ create_dir_depth = 0 ,
337+ )
338+
339+ assert pp ._docs [- 1 ] == start_doc_2
340+ assert pp ._docs [- 1 ]["uid" ] == "27c48d2f-d8c6-4ac0-8146-fedf467ce11f"
341+ assert pp ("det" ) == start_doc_2_path_info
342+
343+ assert pp ._docs [- 2 ] == start_doc_1
344+ assert pp ._docs [- 2 ]["uid" ] == "fa2feced-4098-4c0e-869d-285d2a69c24a"
316345
317- assert pp ( "det" ) == parent_path_info
346+ pp . run_stop ( name = "stop" , stop_document = stop_doc_2 )
318347
319- pp .run_stop (name = "stop" , stop_document = stop_doc )
320- assert pp ._doc == start_doc_default_template
321- assert pp ._doc ["uid" ] == "27c48d2f-d8c6-4ac0-8146-fedf467ce11f" # type: ignore
348+ assert pp ._docs [- 1 ] == start_doc_1
349+ assert pp ._docs [- 1 ]["uid" ] == "fa2feced-4098-4c0e-869d-285d2a69c24a"
322350
323- assert pp ("det" ) == parent_path_info
351+ assert pp ("det" ) == start_doc_1_path_info
324352
325- pp .run_stop (name = "stop" , stop_document = stop_doc_default_template )
326- assert pp ._doc is None
353+ pp .run_stop (name = "stop" , stop_document = stop_doc_1 )
354+ assert pp ._docs == []
327355
328356
329357def test_start_document_path_provider_called_without_start_raises ():
330358 pp = StartDocumentPathProvider ()
331359 with pytest .raises (
332- AttributeError ,
360+ BlueskyRunStructureError ,
333361 match = "Start document not found. This call must be made inside a run." ,
334362 ):
335363 pp ("det" )
364+
365+
366+ def test_start_document_path_provider_run_stop_called_out_of_order_raises (
367+ start_doc_1 : RunStart ,
368+ stop_doc_1 : RunStop ,
369+ start_doc_2 : RunStart ,
370+ ):
371+ pp = StartDocumentPathProvider ()
372+ pp .run_start (name = "start" , start_document = start_doc_1 )
373+ pp .run_start (name = "start" , start_document = start_doc_2 )
374+
375+ with pytest .raises (
376+ BlueskyRunStructureError ,
377+ match = "Close run called, but not for the inner most run. "
378+ "This is not supported. If you need to do this speak to core DAQ." ,
379+ ):
380+ pp .run_stop (name = "stop" , stop_document = stop_doc_1 )
0 commit comments