forked from M-Labs/artiq
hardware_testbench: full shutdown sequence for controllers
This commit is contained in:
parent
53e5d0a7bb
commit
f7df393248
|
@ -8,11 +8,13 @@ import logging
|
||||||
import subprocess
|
import subprocess
|
||||||
import shlex
|
import shlex
|
||||||
import time
|
import time
|
||||||
|
import socket
|
||||||
|
|
||||||
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
|
||||||
from artiq.coredevice.core import CompileError
|
from artiq.coredevice.core import CompileError
|
||||||
from artiq.frontend.artiq_run import DummyScheduler
|
from artiq.frontend.artiq_run import DummyScheduler
|
||||||
|
from artiq.protocols.pc_rpc import AutoTarget, Client
|
||||||
|
|
||||||
|
|
||||||
artiq_root = os.getenv("ARTIQ_ROOT")
|
artiq_root = os.getenv("ARTIQ_ROOT")
|
||||||
|
@ -27,13 +29,13 @@ class ControllerCase(unittest.TestCase):
|
||||||
self.controllers = {}
|
self.controllers = {}
|
||||||
|
|
||||||
def tearDown(self):
|
def tearDown(self):
|
||||||
for name in self.controllers:
|
|
||||||
self.device_mgr.get(name).terminate()
|
|
||||||
self.device_mgr.close_devices()
|
self.device_mgr.close_devices()
|
||||||
for name in list(self.controllers):
|
for name in list(self.controllers):
|
||||||
self.stop_controller(name)
|
self.stop_controller(name)
|
||||||
|
|
||||||
def start_controller(self, name, sleep=1):
|
def start_controller(self, name, sleep=1):
|
||||||
|
if name in self.controllers:
|
||||||
|
raise ValueError("controller `{}` already started".format(name))
|
||||||
try:
|
try:
|
||||||
entry = self.device_db.get(name)
|
entry = self.device_db.get(name)
|
||||||
except KeyError:
|
except KeyError:
|
||||||
|
@ -46,15 +48,43 @@ class ControllerCase(unittest.TestCase):
|
||||||
time.sleep(sleep)
|
time.sleep(sleep)
|
||||||
|
|
||||||
def stop_controller(self, name, default_timeout=1):
|
def stop_controller(self, name, default_timeout=1):
|
||||||
entry, proc = self.controllers[name]
|
desc, proc = self.controllers[name]
|
||||||
t = entry.get("term_timeout", default_timeout)
|
t = desc.get("term_timeout", default_timeout)
|
||||||
proc.terminate()
|
target_name = desc.get("target_name", None)
|
||||||
|
if target_name is None:
|
||||||
|
target_name = AutoTarget
|
||||||
try:
|
try:
|
||||||
proc.wait(t)
|
try:
|
||||||
except subprocess.TimeoutExpired:
|
client = Client(desc["host"], desc["port"], target_name, t)
|
||||||
proc.kill()
|
try:
|
||||||
proc.wait(t)
|
client.terminate()
|
||||||
del self.controllers[name]
|
finally:
|
||||||
|
client.close_rpc()
|
||||||
|
proc.wait(t)
|
||||||
|
return
|
||||||
|
except (socket.timeout, subprocess.TimeoutExpired):
|
||||||
|
logger.warning("Controller %s failed to exit on request", name)
|
||||||
|
try:
|
||||||
|
proc.terminate()
|
||||||
|
except ProcessLookupError:
|
||||||
|
pass
|
||||||
|
try:
|
||||||
|
proc.wait(t)
|
||||||
|
return
|
||||||
|
except subprocess.TimeoutExpired:
|
||||||
|
logger.warning("Controller %s failed to exit on terminate",
|
||||||
|
name)
|
||||||
|
try:
|
||||||
|
proc.kill()
|
||||||
|
except ProcessLookupError:
|
||||||
|
pass
|
||||||
|
try:
|
||||||
|
proc.wait(t)
|
||||||
|
return
|
||||||
|
except subprocess.TimeoutExpired:
|
||||||
|
logger.warning("Controller %s failed to die on kill", name)
|
||||||
|
finally:
|
||||||
|
del self.controllers[name]
|
||||||
|
|
||||||
|
|
||||||
@unittest.skipUnless(artiq_root, "no ARTIQ_ROOT")
|
@unittest.skipUnless(artiq_root, "no ARTIQ_ROOT")
|
||||||
|
|
Loading…
Reference in New Issue