forked from M-Labs/artiq
hardware_testbench: run Crontrollers loop in thread, not the test
This commit is contained in:
parent
99f788965e
commit
1b7020dff3
|
@ -170,9 +170,9 @@ class Controllers:
|
||||||
elif action == "del":
|
elif action == "del":
|
||||||
await self.active[param].end()
|
await self.active[param].end()
|
||||||
del self.active[param]
|
del self.active[param]
|
||||||
else:
|
|
||||||
raise ValueError
|
|
||||||
self.queue.task_done()
|
self.queue.task_done()
|
||||||
|
if action not in ("set", "del"):
|
||||||
|
raise ValueError
|
||||||
|
|
||||||
def __setitem__(self, k, v):
|
def __setitem__(self, k, v):
|
||||||
if (isinstance(v, dict) and v["type"] == "controller" and
|
if (isinstance(v, dict) and v["type"] == "controller" and
|
||||||
|
|
|
@ -6,7 +6,7 @@ import sys
|
||||||
import unittest
|
import unittest
|
||||||
import logging
|
import logging
|
||||||
import asyncio
|
import asyncio
|
||||||
import atexit
|
import threading
|
||||||
|
|
||||||
from artiq.master.databases import DeviceDB, DatasetDB
|
from artiq.master.databases import DeviceDB, DatasetDB
|
||||||
from artiq.master.worker_db import DeviceManager, DatasetManager
|
from artiq.master.worker_db import DeviceManager, DatasetManager
|
||||||
|
@ -30,15 +30,34 @@ class ControllerCase(unittest.TestCase):
|
||||||
else:
|
else:
|
||||||
self.loop = asyncio.new_event_loop()
|
self.loop = asyncio.new_event_loop()
|
||||||
asyncio.set_event_loop(self.loop)
|
asyncio.set_event_loop(self.loop)
|
||||||
atexit.register(self.loop.close)
|
self.addCleanup(self.loop.close)
|
||||||
|
|
||||||
|
self.loop_thread = threading.Thread(target=self.loop.run_forever)
|
||||||
|
self.addCleanup(self.loop_thread.join)
|
||||||
|
self.addCleanup(self.loop.call_soon_threadsafe, self.loop.stop)
|
||||||
|
|
||||||
self.controllers = Controllers()
|
self.controllers = Controllers()
|
||||||
self.controllers.host_filter = self.host_filter
|
self.controllers.host_filter = self.host_filter
|
||||||
|
self.addCleanup(self._stop_controllers)
|
||||||
|
|
||||||
self.device_db = DeviceDB(os.path.join(artiq_root, "device_db.pyon"))
|
self.device_db = DeviceDB(os.path.join(artiq_root, "device_db.pyon"))
|
||||||
self.device_mgr = DeviceManager(self.device_db)
|
self.device_mgr = DeviceManager(self.device_db)
|
||||||
|
self.addCleanup(self.device_mgr.close_devices)
|
||||||
|
|
||||||
|
self.loop_thread.start()
|
||||||
|
|
||||||
|
def _stop_controllers(self):
|
||||||
|
fut = asyncio.run_coroutine_threadsafe(self.controllers.shutdown(),
|
||||||
|
self.loop)
|
||||||
|
fut.result()
|
||||||
|
|
||||||
|
async def _start(self, *names):
|
||||||
|
print("FOOO started")
|
||||||
|
l = asyncio.get_event_loop_policy()
|
||||||
|
l = l.get_event_loop()
|
||||||
|
print("FOOO started")
|
||||||
|
|
||||||
|
|
||||||
async def start(self, *names):
|
|
||||||
for name in names:
|
for name in names:
|
||||||
try:
|
try:
|
||||||
self.controllers[name] = self.device_db.get(name)
|
self.controllers[name] = self.device_db.get(name)
|
||||||
|
@ -46,10 +65,10 @@ class ControllerCase(unittest.TestCase):
|
||||||
raise unittest.SkipTest(
|
raise unittest.SkipTest(
|
||||||
"controller `{}` not found".format(name))
|
"controller `{}` not found".format(name))
|
||||||
await self.controllers.queue.join()
|
await self.controllers.queue.join()
|
||||||
await asyncio.wait([asyncio.ensure_future(self.wait_for_ping(name))
|
await asyncio.wait([self._wait_for_ping(name)
|
||||||
for name in names])
|
for name in names])
|
||||||
|
|
||||||
async def wait_for_ping(self, name, retries=5):
|
async def _wait_for_ping(self, name, retries=5):
|
||||||
t = self.timeout
|
t = self.timeout
|
||||||
dt = t/retries
|
dt = t/retries
|
||||||
while t > 0:
|
while t > 0:
|
||||||
|
@ -68,27 +87,9 @@ class ControllerCase(unittest.TestCase):
|
||||||
t -= dt
|
t -= dt
|
||||||
raise asyncio.TimeoutError
|
raise asyncio.TimeoutError
|
||||||
|
|
||||||
|
def start_controllers(self, *names):
|
||||||
def with_controllers(*names):
|
fut = asyncio.run_coroutine_threadsafe(self._start(*names), self.loop)
|
||||||
def wrapper(func):
|
fut.result()
|
||||||
def inner(self):
|
|
||||||
try:
|
|
||||||
for name in names:
|
|
||||||
setattr(self, name, self.device_mgr.get(name))
|
|
||||||
func(self)
|
|
||||||
finally:
|
|
||||||
self.device_mgr.close_devices()
|
|
||||||
|
|
||||||
def wrapped_test(self):
|
|
||||||
try:
|
|
||||||
self.loop.run_until_complete(self.start(*names))
|
|
||||||
self.loop.run_until_complete(self.loop.run_in_executor(
|
|
||||||
None, inner, self))
|
|
||||||
finally:
|
|
||||||
self.loop.run_until_complete(self.controllers.shutdown())
|
|
||||||
|
|
||||||
return wrapped_test
|
|
||||||
return wrapper
|
|
||||||
|
|
||||||
|
|
||||||
@unittest.skipUnless(artiq_root, "no ARTIQ_ROOT")
|
@unittest.skipUnless(artiq_root, "no ARTIQ_ROOT")
|
||||||
|
|
|
@ -2,7 +2,7 @@ import unittest
|
||||||
|
|
||||||
from artiq.devices.lda.driver import Ldasim
|
from artiq.devices.lda.driver import Ldasim
|
||||||
from artiq.language.units import dB
|
from artiq.language.units import dB
|
||||||
from artiq.test.hardware_testbench import ControllerCase, with_controllers
|
from artiq.test.hardware_testbench import ControllerCase
|
||||||
|
|
||||||
|
|
||||||
class GenericLdaTest:
|
class GenericLdaTest:
|
||||||
|
@ -18,10 +18,10 @@ class GenericLdaTest:
|
||||||
|
|
||||||
|
|
||||||
class TestLda(ControllerCase, GenericLdaTest):
|
class TestLda(ControllerCase, GenericLdaTest):
|
||||||
@with_controllers("lda")
|
def setUp(self):
|
||||||
def test_attenuation(self):
|
ControllerCase.setUp(self)
|
||||||
|
self.start_controllers("lda")
|
||||||
self.cont = self.device_mgr.get("lda")
|
self.cont = self.device_mgr.get("lda")
|
||||||
GenericLdaTest.test_attenuation(self)
|
|
||||||
|
|
||||||
|
|
||||||
class TestLdaSim(GenericLdaTest, unittest.TestCase):
|
class TestLdaSim(GenericLdaTest, unittest.TestCase):
|
||||||
|
|
Loading…
Reference in New Issue