1
1
from 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
5
3
import pytest
6
4
import threading
7
- import numpy
8
- import re
9
- import yaml
10
- import time
11
5
12
6
DEVICE_NAME = "MY-DEVICE"
13
7
14
8
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
15
31
16
- def test_context_manager_thread_safety (tmp_path ):
32
+
33
+ def create_many_threads (tmp_path ):
17
34
autosave .configure (tmp_path , DEVICE_NAME )
18
35
in_cm_event = threading .Event ()
19
36
@@ -31,3 +48,219 @@ def create_pv_in_thread(name):
31
48
in_cm_event .set ()
32
49
builder .aOut ("PV-FROM-CM" )
33
50
[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