Skip to content

Commit 62ada36

Browse files
Add test for AsyncioDispatcher as ContextManager
1 parent 101192c commit 62ada36

File tree

1 file changed

+79
-1
lines changed

1 file changed

+79
-1
lines changed

tests/test_asyncio.py

+79-1
Original file line numberDiff line numberDiff line change
@@ -4,9 +4,14 @@
44

55
from multiprocessing.connection import Listener
66

7-
from conftest import requires_cothread, ADDRESS, select_and_recv
7+
from conftest import (
8+
ADDRESS, select_and_recv,
9+
log, get_multiprocessing_context, TIMEOUT,
10+
create_random_prefix
11+
)
812

913
from softioc.asyncio_dispatcher import AsyncioDispatcher
14+
from softioc import builder, softioc
1015

1116
@pytest.mark.asyncio
1217
async def test_asyncio_ioc(asyncio_ioc):
@@ -131,3 +136,76 @@ def test_asyncio_dispatcher_event_loop():
131136
event_loop = asyncio.get_event_loop()
132137
with pytest.raises(ValueError):
133138
AsyncioDispatcher(loop=event_loop)
139+
140+
def asyncio_dispatcher_test_func(device_name, child_conn):
141+
142+
log("CHILD: Child started")
143+
144+
builder.SetDeviceName(device_name)
145+
146+
147+
with AsyncioDispatcher() as dispatcher:
148+
# Create some records
149+
ai = builder.aIn('AI', initial_value=5)
150+
builder.aOut('AO', initial_value=12.45, always_update=True,
151+
on_update=lambda v: ai.set(v))
152+
153+
# Boilerplate get the IOC started
154+
builder.LoadDatabase()
155+
softioc.iocInit(dispatcher)
156+
157+
# Start processes required to be run after iocInit
158+
async def update():
159+
while True:
160+
ai.set(ai.get() + 1)
161+
await asyncio.sleep(0.01)
162+
163+
dispatcher(update)
164+
165+
log("CHILD: Sending Ready")
166+
child_conn.send("R")
167+
168+
# Keep process alive while main thread runs CAGET
169+
if child_conn.poll(TIMEOUT):
170+
val = child_conn.recv()
171+
assert val == "D", "Did not receive expected Done character"
172+
173+
174+
175+
def test_asyncio_dispatcher_as_context_manager():
176+
"""Test that the asyncio dispatcher can be used as a context manager"""
177+
ctx = get_multiprocessing_context()
178+
parent_conn, child_conn = ctx.Pipe()
179+
180+
device_name = create_random_prefix()
181+
182+
process = ctx.Process(
183+
target=asyncio_dispatcher_test_func,
184+
args=(device_name, child_conn),
185+
)
186+
187+
process.start()
188+
189+
log("PARENT: Child started, waiting for R command")
190+
191+
# from aioca import caget, purge_channel_caches
192+
import cothread
193+
from cothread.catools import caget
194+
try:
195+
# Wait for message that IOC has started
196+
select_and_recv(parent_conn, "R")
197+
198+
# ao_val = await caget(device_name + ":AO")
199+
ao_val = caget(device_name + ":AO")
200+
assert ao_val == 12.45
201+
202+
# Confirm the value of the AI record is increasing
203+
ai_val_1 = caget(device_name + ":AI")
204+
cothread.Sleep(0.1)
205+
ai_val_2 = caget(device_name + ":AI")
206+
assert ai_val_2 > ai_val_1
207+
208+
finally:
209+
parent_conn.send("D") # "Done"
210+
process.join(timeout=TIMEOUT)
211+
assert process.exitcode == 0 # clean exit

0 commit comments

Comments
 (0)