def at2l0(request): signals = { 0: ophyd.Signal(value=0, name="moving"), 1: ophyd.Signal(value=1, name="out"), 2: ophyd.Signal(value=2, name="in"), 3: ophyd.Signal(value=3, name="unknown"), } class FakeAT2L0: name: str = "fakedev" state_attrs: List[str] = ( "blade_01.state.state blade_02.state.state blade_03.state.state " "blade_04.state.state blade_05.state.state blade_06.state.state " "blade_07.state.state blade_08.state.state blade_09.state.state " "blade_10.state.state blade_11.state.state blade_12.state.state " "blade_13.state.state blade_14.state.state blade_15.state.state " "blade_16.state.state blade_17.state.state blade_18.state.state " "blade_19.state.state").split() def __getattr__(self, attr): if attr.startswith("blade_"): return signals[request.param] raise AttributeError(attr) return FakeAT2L0()
def test_pre_suspend_plan(fresh_RE, pre_plan, post_plan, expected_list): RE = fresh_RE sig = ophyd.Signal() scan = [Msg('checkpoint'), Msg('sleep', None, .2)] msg_lst = [] sig.put(0) def accum(msg): msg_lst.append(msg) susp = SuspendBoolHigh(sig, pre_plan=pre_plan, post_plan=post_plan) RE.install_suspender(susp) RE._loop.call_later(.1, sig.put, 1) RE._loop.call_later(1, sig.put, 0) RE.msg_hook = accum RE(scan) assert len(msg_lst) == len(expected_list) assert expected_list == [m[0] for m in msg_lst] RE.remove_suspender(susp) RE(scan) assert susp.RE is None RE.install_suspender(susp) RE.clear_suspenders() assert susp.RE is None assert not RE.suspenders
def test_suspender(klass, sc_args, start_val, fail_val, resume_val, wait_time, fresh_RE): RE = fresh_RE loop = RE._loop sig = ophyd.Signal() my_suspender = klass(sig, *sc_args, sleep=wait_time) my_suspender.install(RE) def putter(val): sig.put(val) # make sure we start at good value! putter(start_val) # dumb scan scan = [Msg('checkpoint'), Msg('sleep', None, .2)] RE(scan) # paranoid assert RE.state == 'idle' start = ttime.time() # queue up fail and resume conditions loop.call_later(.1, putter, fail_val) loop.call_later(.5, putter, resume_val) # start the scan RE(scan) stop = ttime.time() # assert we waited at least 2 seconds + the settle time delta = stop - start print(delta) assert delta > .5 + wait_time + .2
def test_set_beamdump_suspender(self): # operate at full current sig = ophyd.Signal(name="ring_current") xpd_configuration["ring_current"] = sig set_beamdump_suspender(self.xrun, wait_time=0.1) sig.put(200) self.xrun({}, ScanPlan(self.bt, ct, .1)) # operate at low current, test user warnning with warnings.catch_warnings(record=True) as w: warnings.simplefilter("always") # trigger warning sig.put(30) # low current set_beamdump_suspender(self.xrun, wait_time=0.1) # check warning assert len(w) == 1 assert issubclass(w[-1].category, UserWarning)
def test_exception_non_duplicates( callback_demoter: pcdsutils.log.OphydCallbackExceptionDemoter, caplog: pytest.LogCaptureFixture, ): caplog.set_level(logging.DEBUG) callback_demoter.only_duplicates = False def varied_exception(*args, value, **kwargs): raise RuntimeError(f'Varied exception value={value}') sig = ophyd.Signal(name='sig') sig.subscribe(varied_exception, run=False) def inner_test(filtered: bool): callback_demoter.reset_counter() total_cnt = 10 for cnt in range(total_cnt): caplog.clear() sig.put(cnt) target_records = [ rec for rec in caplog.records if rec.name == 'ophyd.objects' ] assert target_records, ( f"Did not find object log records! cnt={cnt}" ) assert len(target_records) == 1, ( f"Too many records! cnt={cnt}" ) record = target_records[0] if not filtered: assert record.levelno == logging.ERROR, ( f"filtered={filtered}, cnt={cnt}" ) else: assert record.levelno == logging.DEBUG, ( f"filtered={filtered}, cnt={cnt}" ) assert "Varied exception" in record.exc_text if filtered: assert callback_demoter.counter == total_cnt else: assert callback_demoter.counter == 0 inner_test(filtered=True) callback_demoter.uninstall() inner_test(filtered=False)
def test_exception_filter( callback_demoter: pcdsutils.log.OphydCallbackExceptionDemoter, caplog: pytest.LogCaptureFixture, ): caplog.set_level(logging.DEBUG) def zerodiv(*args, **kwargs): 1/0 sig = ophyd.Signal(name='sig') sig.subscribe(zerodiv, run=False) def inner_test(filtered: bool): callback_demoter.reset_counter() total_cnt = 10 for cnt in range(total_cnt): caplog.clear() sig.put(cnt) target_records = [ rec for rec in caplog.records if rec.name == 'ophyd.objects' ] assert target_records, ( f"Did not find object log records! cnt={cnt}" ) assert len(target_records) == 1, ( f"Too many records! cnt={cnt}" ) record = target_records[0] if not filtered or cnt == 0: assert record.levelno == logging.ERROR, ( f"filtered={filtered}, cnt={cnt}" ) else: assert record.levelno == logging.DEBUG, ( f"filtered={filtered}, cnt={cnt}" ) assert "ZeroDivisionError" in record.exc_text if filtered: assert callback_demoter.counter == total_cnt - 1 else: assert callback_demoter.counter == 0 inner_test(filtered=True) callback_demoter.uninstall() inner_test(filtered=False)
def test_pretripped(fresh_RE): 'Tests if suspender is tripped before __call__' RE = fresh_RE sig = ophyd.Signal() scan = [Msg('checkpoint')] msg_lst = [] sig.put(1) def accum(msg): msg_lst.append(msg) susp = SuspendBoolHigh(sig) RE.install_suspender(susp) RE._loop.call_later(1, sig.put, 0) RE.msg_hook = accum RE(scan) assert len(msg_lst) == 2 assert ['wait_for', 'checkpoint'] == [m[0] for m in msg_lst]
def test_pause_from_suspend(fresh_RE): 'Tests what happens when a pause is requested from a suspended state' RE = fresh_RE sig = ophyd.Signal() scan = [Msg('checkpoint')] msg_lst = [] sig.put(1) def accum(msg): msg_lst.append(msg) susp = SuspendBoolHigh(sig) RE.install_suspender(susp) RE._loop.call_later(1, RE.request_pause) RE._loop.call_later(2, sig.put, 0) RE.msg_hook = accum RE(scan) assert [m[0] for m in msg_lst] == ['wait_for'] RE.resume() assert ['wait_for', 'wait_for', 'checkpoint'] == [m[0] for m in msg_lst]
def test_set_beamdump_suspender(self): loop = self.xrun._loop # no suspender self.xrun({}, ScanPlan(self.bt, ct, 1)) # operate at full current sig = ophyd.Signal(name="ring_current") def putter(val): sig.put(val) xpd_configuration["ring_current"] = sig putter(200) wait_time = 0.2 set_beamdump_suspender(self.xrun, wait_time=wait_time) # test start = time.time() # queue up fail and resume conditions loop.call_later(.1, putter, 90) # lower than 50%, trigger loop.call_later(1., putter, 190) # higher than 90%, resume # start the scan self.xrun({}, ScanPlan(self.bt, ct, .1)) stop = time.time() # assert we waited at least 2 seconds + # the settle time delta = stop - start print(delta) assert delta > .1 + wait_time + 1. # operate at low current, test user warnning with warnings.catch_warnings(record=True) as w: warnings.simplefilter("always") # trigger warning putter(30) # low current set_beamdump_suspender(self.xrun, wait_time=wait_time) # check warning assert len(w) == 1 assert issubclass(w[-1].category, UserWarning)
# flake8: noqa import time as ttime import typing import ophyd from ophyd import Device, Component as Cpt # Keep 'Device' imported, used in unit tests import bluesky import bluesky.preprocessors as bpp import bluesky.plan_stubs as bps from bluesky_queueserver.manager.annotation_decorator import parameter_annotation_decorator # Some useless devices for unit tests. custom_test_device = ophyd.Device(name="custom_test_device") custom_test_signal = ophyd.Signal(name="custom_test_signal") custom_test_flyer = ophyd.sim.MockFlyer("custom_test_flyer", ophyd.sim.det, ophyd.sim.motor, 1, 5, 20) @parameter_annotation_decorator({ "description": "Move motors into positions; then count dets.", "parameters": { "motors": { "description": "List of motors to be moved into specified positions before the measurement", "annotation": "typing.List[Motors]", "devices": { "Motors": ("motor1", "motor2") }, }, "detectors": { "description": "Detectors to use for measurement.", "annotation": "typing.List[Detectors]",
def sig(): name = 'test{}'.format(random.randint(0, 10000)) sig = ophyd.Signal(name=name) yield sig sig.destroy()
class Device: name = "dev" sig1 = ophyd.Signal(value=1, name="dev.sig1") sig2 = ophyd.Signal(value=2.5, name="dev.sig2") sig3 = ophyd.Signal(value="abc", name="dev.sig3")