11from typing import List
2- from conftest import get_multiprocessing_context , select_and_recv
3- from softioc import autosave , builder , softioc , device_core , asyncio_dispatcher
4- from unittest .mock import patch
2+ from softioc import autosave , builder , device_core
53import pytest
64import threading
7- import numpy
8- import re
9- import yaml
10- import time
115
126DEVICE_NAME = "MY-DEVICE"
137
148
9+ @pytest .fixture (autouse = True )
10+ def reset_autosave_setup_teardown ():
11+ default_save_period = autosave .AutosaveConfig .save_period
12+ default_device_name = autosave .AutosaveConfig .device_name
13+ default_directory = autosave .AutosaveConfig .directory
14+ default_enabled = autosave .AutosaveConfig .enabled
15+ default_tb = autosave .AutosaveConfig .timestamped_backups
16+ default_pvs = autosave .Autosave ._pvs .copy ()
17+ default_state = autosave .Autosave ._last_saved_state .copy ()
18+ default_cm_save_fields = autosave ._AutosaveContext ._fields
19+ default_instance = autosave ._AutosaveContext ._instance
20+ yield
21+ autosave .AutosaveConfig .save_period = default_save_period
22+ autosave .AutosaveConfig .device_name = default_device_name
23+ autosave .AutosaveConfig .directory = default_directory
24+ autosave .AutosaveConfig .enabled = default_enabled
25+ autosave .AutosaveConfig .timestamped_backups = default_tb
26+ autosave .Autosave ._pvs = default_pvs
27+ autosave .Autosave ._last_saved_state = default_state
28+ autosave .Autosave ._stop_event = threading .Event ()
29+ autosave ._AutosaveContext ._fields = default_cm_save_fields
30+ autosave ._AutosaveContext ._instance = default_instance
1531
16- def test_context_manager_thread_safety (tmp_path ):
32+
33+ def create_many_threads (tmp_path ):
1734 autosave .configure (tmp_path , DEVICE_NAME )
1835 in_cm_event = threading .Event ()
1936
@@ -31,3 +48,219 @@ def create_pv_in_thread(name):
3148 in_cm_event .set ()
3249 builder .aOut ("PV-FROM-CM" )
3350 [x .join () for x in threads ]
51+
52+ def original_test_1 (tmp_path ):
53+ autosave .configure (tmp_path , DEVICE_NAME )
54+ in_cm_event = threading .Event ()
55+
56+ def create_pv_in_thread (name ):
57+ in_cm_event .wait ()
58+ builder .aOut (name , autosave = False )
59+ pv_thread_before_cm = threading .Thread (
60+ target = create_pv_in_thread , args = ["PV-FROM-THREAD-BEFORE" ])
61+ pv_thread_in_cm = threading .Thread (
62+ target = create_pv_in_thread , args = ["PV-FROM-THREAD-DURING" ])
63+ pv_thread_before_cm .start ()
64+ with autosave .Autosave (["VAL" , "EGU" ]):
65+ in_cm_event .set ()
66+ builder .aOut ("PV-FROM-CM" )
67+ pv_thread_in_cm .start ()
68+ pv_thread_in_cm .join ()
69+ pv_thread_before_cm .join ()
70+
71+ assert "PV-FROM-THREAD-BEFORE" not in autosave .Autosave ._pvs
72+ assert "PV-FROM-THREAD-DURING" not in autosave .Autosave ._pvs
73+ assert device_core .LookupRecord ("PV-FROM-THREAD-BEFORE" )
74+ assert device_core .LookupRecord ("PV-FROM-THREAD-DURING" )
75+
76+ def original_test_2 (tmp_path ):
77+ autosave .configure (tmp_path , DEVICE_NAME )
78+ in_cm_event = threading .Event ()
79+
80+ def create_pv_in_thread (name ):
81+ in_cm_event .wait ()
82+ builder .aOut (name , autosave = False )
83+ pv_thread_before_cm = threading .Thread (
84+ target = create_pv_in_thread , args = ["PV-FROM-THREAD-BEFORE" ])
85+ pv_thread_in_cm = threading .Thread (
86+ target = create_pv_in_thread , args = ["PV-FROM-THREAD-DURING" ])
87+ pv_thread_before_cm .start ()
88+ with autosave .Autosave (["VAL" , "EGU" ]):
89+ in_cm_event .set ()
90+ builder .aOut ("PV-FROM-CM" )
91+ pv_thread_in_cm .start ()
92+ pv_thread_in_cm .join ()
93+ pv_thread_before_cm .join ()
94+
95+ assert "PV-FROM-THREAD-BEFORE" not in autosave .Autosave ._pvs
96+ assert "PV-FROM-THREAD-DURING" not in autosave .Autosave ._pvs
97+ assert device_core .LookupRecord ("PV-FROM-THREAD-BEFORE" )
98+ assert device_core .LookupRecord ("PV-FROM-THREAD-DURING" )
99+
100+ def original_test_3 (tmp_path ):
101+ autosave .configure (tmp_path , DEVICE_NAME )
102+ in_cm_event = threading .Event ()
103+
104+ def create_pv_in_thread (name ):
105+ in_cm_event .wait ()
106+ builder .aOut (name , autosave = False )
107+ pv_thread_before_cm = threading .Thread (
108+ target = create_pv_in_thread , args = ["PV-FROM-THREAD-BEFORE" ])
109+ pv_thread_in_cm = threading .Thread (
110+ target = create_pv_in_thread , args = ["PV-FROM-THREAD-DURING" ])
111+ pv_thread_before_cm .start ()
112+ with autosave .Autosave (["VAL" , "EGU" ]):
113+ in_cm_event .set ()
114+ builder .aOut ("PV-FROM-CM" )
115+ pv_thread_in_cm .start ()
116+ pv_thread_in_cm .join ()
117+ pv_thread_before_cm .join ()
118+
119+ assert "PV-FROM-THREAD-BEFORE" not in autosave .Autosave ._pvs
120+ assert "PV-FROM-THREAD-DURING" not in autosave .Autosave ._pvs
121+ assert device_core .LookupRecord ("PV-FROM-THREAD-BEFORE" )
122+ assert device_core .LookupRecord ("PV-FROM-THREAD-DURING" )
123+
124+ def original_test_4 (tmp_path ):
125+ autosave .configure (tmp_path , DEVICE_NAME )
126+ in_cm_event = threading .Event ()
127+
128+ def create_pv_in_thread (name ):
129+ in_cm_event .wait ()
130+ builder .aOut (name , autosave = False )
131+ pv_thread_before_cm = threading .Thread (
132+ target = create_pv_in_thread , args = ["PV-FROM-THREAD-BEFORE" ])
133+ pv_thread_in_cm = threading .Thread (
134+ target = create_pv_in_thread , args = ["PV-FROM-THREAD-DURING" ])
135+ pv_thread_before_cm .start ()
136+ with autosave .Autosave (["VAL" , "EGU" ]):
137+ in_cm_event .set ()
138+ builder .aOut ("PV-FROM-CM" )
139+ pv_thread_in_cm .start ()
140+ pv_thread_in_cm .join ()
141+ pv_thread_before_cm .join ()
142+
143+ assert "PV-FROM-THREAD-BEFORE" not in autosave .Autosave ._pvs
144+ assert "PV-FROM-THREAD-DURING" not in autosave .Autosave ._pvs
145+ assert device_core .LookupRecord ("PV-FROM-THREAD-BEFORE" )
146+ assert device_core .LookupRecord ("PV-FROM-THREAD-DURING" )
147+
148+ def original_test_5 (tmp_path ):
149+ autosave .configure (tmp_path , DEVICE_NAME )
150+ in_cm_event = threading .Event ()
151+
152+ def create_pv_in_thread (name ):
153+ in_cm_event .wait ()
154+ builder .aOut (name , autosave = False )
155+ pv_thread_before_cm = threading .Thread (
156+ target = create_pv_in_thread , args = ["PV-FROM-THREAD-BEFORE" ])
157+ pv_thread_in_cm = threading .Thread (
158+ target = create_pv_in_thread , args = ["PV-FROM-THREAD-DURING" ])
159+ pv_thread_before_cm .start ()
160+ with autosave .Autosave (["VAL" , "EGU" ]):
161+ in_cm_event .set ()
162+ builder .aOut ("PV-FROM-CM" )
163+ pv_thread_in_cm .start ()
164+ pv_thread_in_cm .join ()
165+ pv_thread_before_cm .join ()
166+
167+ assert "PV-FROM-THREAD-BEFORE" not in autosave .Autosave ._pvs
168+ assert "PV-FROM-THREAD-DURING" not in autosave .Autosave ._pvs
169+ assert device_core .LookupRecord ("PV-FROM-THREAD-BEFORE" )
170+ assert device_core .LookupRecord ("PV-FROM-THREAD-DURING" )
171+
172+ def original_test_6 (tmp_path ):
173+ autosave .configure (tmp_path , DEVICE_NAME )
174+ in_cm_event = threading .Event ()
175+
176+ def create_pv_in_thread (name ):
177+ in_cm_event .wait ()
178+ builder .aOut (name , autosave = False )
179+ pv_thread_before_cm = threading .Thread (
180+ target = create_pv_in_thread , args = ["PV-FROM-THREAD-BEFORE" ])
181+ pv_thread_in_cm = threading .Thread (
182+ target = create_pv_in_thread , args = ["PV-FROM-THREAD-DURING" ])
183+ pv_thread_before_cm .start ()
184+ with autosave .Autosave (["VAL" , "EGU" ]):
185+ in_cm_event .set ()
186+ builder .aOut ("PV-FROM-CM" )
187+ pv_thread_in_cm .start ()
188+ pv_thread_in_cm .join ()
189+ pv_thread_before_cm .join ()
190+
191+ assert "PV-FROM-THREAD-BEFORE" not in autosave .Autosave ._pvs
192+ assert "PV-FROM-THREAD-DURING" not in autosave .Autosave ._pvs
193+ assert device_core .LookupRecord ("PV-FROM-THREAD-BEFORE" )
194+ assert device_core .LookupRecord ("PV-FROM-THREAD-DURING" )
195+
196+ def original_test_7 (tmp_path ):
197+ autosave .configure (tmp_path , DEVICE_NAME )
198+ in_cm_event = threading .Event ()
199+
200+ def create_pv_in_thread (name ):
201+ in_cm_event .wait ()
202+ builder .aOut (name , autosave = False )
203+ pv_thread_before_cm = threading .Thread (
204+ target = create_pv_in_thread , args = ["PV-FROM-THREAD-BEFORE" ])
205+ pv_thread_in_cm = threading .Thread (
206+ target = create_pv_in_thread , args = ["PV-FROM-THREAD-DURING" ])
207+ pv_thread_before_cm .start ()
208+ with autosave .Autosave (["VAL" , "EGU" ]):
209+ in_cm_event .set ()
210+ builder .aOut ("PV-FROM-CM" )
211+ pv_thread_in_cm .start ()
212+ pv_thread_in_cm .join ()
213+ pv_thread_before_cm .join ()
214+
215+ assert "PV-FROM-THREAD-BEFORE" not in autosave .Autosave ._pvs
216+ assert "PV-FROM-THREAD-DURING" not in autosave .Autosave ._pvs
217+ assert device_core .LookupRecord ("PV-FROM-THREAD-BEFORE" )
218+ assert device_core .LookupRecord ("PV-FROM-THREAD-DURING" )
219+
220+ def original_test_8 (tmp_path ):
221+ autosave .configure (tmp_path , DEVICE_NAME )
222+ in_cm_event = threading .Event ()
223+
224+ def create_pv_in_thread (name ):
225+ in_cm_event .wait ()
226+ builder .aOut (name , autosave = False )
227+ pv_thread_before_cm = threading .Thread (
228+ target = create_pv_in_thread , args = ["PV-FROM-THREAD-BEFORE" ])
229+ pv_thread_in_cm = threading .Thread (
230+ target = create_pv_in_thread , args = ["PV-FROM-THREAD-DURING" ])
231+ pv_thread_before_cm .start ()
232+ with autosave .Autosave (["VAL" , "EGU" ]):
233+ in_cm_event .set ()
234+ builder .aOut ("PV-FROM-CM" )
235+ pv_thread_in_cm .start ()
236+ pv_thread_in_cm .join ()
237+ pv_thread_before_cm .join ()
238+
239+ assert "PV-FROM-THREAD-BEFORE" not in autosave .Autosave ._pvs
240+ assert "PV-FROM-THREAD-DURING" not in autosave .Autosave ._pvs
241+ assert device_core .LookupRecord ("PV-FROM-THREAD-BEFORE" )
242+ assert device_core .LookupRecord ("PV-FROM-THREAD-DURING" )
243+
244+ def original_test_9 (tmp_path ):
245+ autosave .configure (tmp_path , DEVICE_NAME )
246+ in_cm_event = threading .Event ()
247+
248+ def create_pv_in_thread (name ):
249+ in_cm_event .wait ()
250+ builder .aOut (name , autosave = False )
251+ pv_thread_before_cm = threading .Thread (
252+ target = create_pv_in_thread , args = ["PV-FROM-THREAD-BEFORE" ])
253+ pv_thread_in_cm = threading .Thread (
254+ target = create_pv_in_thread , args = ["PV-FROM-THREAD-DURING" ])
255+ pv_thread_before_cm .start ()
256+ with autosave .Autosave (["VAL" , "EGU" ]):
257+ in_cm_event .set ()
258+ builder .aOut ("PV-FROM-CM" )
259+ pv_thread_in_cm .start ()
260+ pv_thread_in_cm .join ()
261+ pv_thread_before_cm .join ()
262+
263+ assert "PV-FROM-THREAD-BEFORE" not in autosave .Autosave ._pvs
264+ assert "PV-FROM-THREAD-DURING" not in autosave .Autosave ._pvs
265+ assert device_core .LookupRecord ("PV-FROM-THREAD-BEFORE" )
266+ assert device_core .LookupRecord ("PV-FROM-THREAD-DURING" )
0 commit comments