def get_shuffleable_scan_generators(): scans = get_scan_generators() RE = setup_test_run_engine() unshuffleable = [] for scan in scans: print("Testing to see if {} is shufflable".format( scan.__code__.co_name)) scan_gen = make_scan_from_gen_func(scan) # turn it into a list try: scan_list = list(scan_gen) except TypeError as te: print("{} is not shuffleable. Error: {}".format( scan.__code__.co_name, te)) unshuffleable.append(scan) # then shuffle it random.shuffle(scan_list) try: if RE.state != 'idle': RE.abort() RE(scan_list) except (IllegalMessageSequence, ValueError): # this is acceptable pass return [scan for scan in scans if scan not in unshuffleable]
def get_shuffleable_scan_generators(): scans = get_scan_generators() RE = setup_test_run_engine() unshuffleable = [] for scan in scans: print("Testing to see if {} is shufflable".format( scan.__code__.co_name)) scan_gen = make_scan_from_gen_func(scan) # turn it into a list try: scan_list = list(scan_gen) except TypeError as te: print("{} is not shuffleable. Error: {}".format( scan.__code__.co_name, te)) unshuffleable.append(scan) # then shuffle it random.shuffle(scan_list) try: if RE.state != 'idle': RE.abort() RE(scan_list) except IllegalMessageSequence: # this is acceptable pass return [scan for scan in scans if scan not in unshuffleable]
def test_round_trip_from_run_engine(): try: import bluesky except ImportError as ie: raise pytest.skip('ImportError: {0}'.format(ie)) # generate a new specfile from bluesky.tests.utils import setup_test_run_engine from bluesky.examples import motor, det from bluesky.plans import RelativeScan, Scan, Count RE = setup_test_run_engine() RE.ignore_callback_exceptions = False fname = tempfile.NamedTemporaryFile().name cb = DocumentToSpec(fname) dscan = RelativeScan([det], motor, -1, 1, 10) RE(dscan, {'all': cb}) ascan = Scan([det], motor, -1, 1, 10) RE(ascan, {'all': cb}) # add count to hit some lines in # suitcase.spec:_get_motor_name # suitcase.spec:_get_motor_position # suitcase.spec:_get_plan_type ct = Count([det]) RE(ct, {'all': cb}) sf = Specfile(fname) sf1 = _round_trip(sf) assert len(sf) == len(sf1)
def test_round_trip_from_run_engine(): try: import bluesky except ImportError as ie: raise pytest.skip('ImportError: {0}'.format(ie)) # generate a new specfile from bluesky.tests.utils import setup_test_run_engine from bluesky.examples import motor, det from bluesky.global_state import gs from bluesky.spec_api import dscan, ascan, ct RE = setup_test_run_engine() RE.ignore_callback_exceptions = False fname = tempfile.NamedTemporaryFile().name cb = DocumentToSpec(fname) RE.subscribe('all', cb) gs.DETS = [det] RE(dscan(motor, -1, 1, 10)) RE(ascan(motor, -1, 1, 10)) # add count to hit some lines in # suitcase.spec:_get_motor_name # suitcase.spec:_get_motor_position # suitcase.spec:_get_plan_type RE(ct()) sf = Specfile(fname) sf1 = _round_trip(sf) assert len(sf) == len(sf1)
def test_round_trip_from_run_engine(mds_all): try: import bluesky except ImportError as ie: raise pytest.skip('ImportError: {0}'.format(ie)) # generate a new specfile from bluesky.tests.utils import setup_test_run_engine from bluesky.examples import motor, det, motor1 from bluesky.global_state import gs from bluesky.spec_api import dscan, ascan, ct, a2scan RE = setup_test_run_engine() fname = tempfile.NamedTemporaryFile().name cb = spec.DocumentToSpec(fname) RE.subscribe('all', cb) gs.DETS = [det] RE(dscan(motor, -1, 1, 10)) RE(ascan(motor, -1, 1, 10)) # add count to hit some lines in # suitcase.spec:_get_motor_name # suitcase.spec:_get_motor_position # suitcase.spec:_get_plan_type RE(ct()) RE(a2scan(motor, -1, 1, motor1, -1, 1, 10)) sf = spec.Specfile(fname) sf1 = _round_trip(sf, mds_all) # a2scan is not round trippable num_unconvertable_scans = 1 assert len(sf) == (len(sf1) + num_unconvertable_scans)
def test_dscan_logbook(): result = {} def logbook(m, d): result['msg'] = m RE = setup_test_run_engine() RE.logbook = logbook d = DeltaScan([det], motor, 1, 2, 2) RE(d) assert_true(result['msg'].startswith(EXPECTED_FORMAT_STR))
def run_engine(ipython, monkeypatch): from bluesky.tests.utils import setup_test_run_engine run_engine = setup_test_run_engine() new_md = dict(run_engine.md) new_md.update(ipython.user_ns['gs'].RE.md) run_engine.md = new_md run_engine.ignore_callback_exceptions = False return run_engine
def test_dets(db, tmp_dir, name, fp): det = det_factory(name, db.fs, fp, save_path=tmp_dir) RE = setup_test_run_engine() RE.subscribe('all', db.mds.insert) scan = Count([det], ) uid = RE(scan) db.fs.register_handler('RWFS_NPY', be.ReaderWithFSHandler) cycle2 = build_image_cycle(fp) cg = cycle2() for n, d in db.restream(db[-1], fill=True): if n == 'event': assert_array_equal(d['data']['pe1_image'], next(cg)['pe1_image']) assert uid is not None
def test_dets_shutter(db, tmp_dir, name, fp): det = det_factory(name, db.fs, fp, save_path=tmp_dir, shutter=shctl1) RE = setup_test_run_engine() RE.subscribe('all', db.mds.insert) scan = Count([det], ) db.fs.register_handler('RWFS_NPY', be.ReaderWithFSHandler) cycle2 = build_image_cycle(fp) cg = cycle2() # With the shutter down RE(abs_set(shctl1, 0, wait=True)) uid = RE(scan) for n, d in db.restream(db[-1], fill=True): if n == 'event': assert_array_equal(d['data']['pe1_image'], np.zeros(next(cg)['pe1_image'].shape)) assert uid is not None # With the shutter up RE(abs_set(shctl1, 1, wait=True)) uid = RE(scan) for n, d in db.restream(db[-1], fill=True): if n == 'event': assert_array_equal(d['data']['pe1_image'], next(cg)['pe1_image']) assert uid is not None
from xray_vision.backend.mpl.cross_section_2d import CrossSection import numpy as np import filestore.api as fsapi import time as ttime from filestore.handlers import NpyHandler fsapi.register_handler('npy', NpyHandler) def stepscan(det, motor): for i in np.linspace(-5, 5, 75): yield Msg('open_run') yield Msg('create') yield Msg('set', motor, i) yield Msg('trigger', det) yield Msg('read', motor) yield Msg('read', det) yield Msg('save') yield Msg('close_run') ic = LiveImage('det_2d') table_callback = LiveTable(fields=[motor._name, det_2d._name]) RE = setup_test_run_engine() RE(stepscan(det_2d, motor), subs={ 'event': ic, 'all': table_callback }, beamline_id='c08i')
from bluesky.testing.noseclasses import KnownFailureTest import os import signal import asyncio import time as ttime try: import matplotlib.pyplot as plt del plt except ImportError: skip_mpl = True else: skip_mpl = False RE = setup_test_run_engine() def test_msgs(): m = Msg('set', motor, {'motor': 5}) assert_equal(m.command, 'set') assert_is(m.obj, motor) assert_equal(m.args, ({'motor': 5},)) assert_equal(m.kwargs, {}) m = Msg('read', motor) assert_equal(m.command, 'read') assert_is(m.obj, motor) assert_equal(m.args, ()) assert_equal(m.kwargs, {})
def run_fuzz(): loop = asyncio.get_event_loop() # create 10 different flyers with corresponding kickoff and collect # messages flyer_messages = [ msg for _ in range(10) for msg in kickoff_and_collect(block=random.random() > 0.5, magic=random.random() > 0.5) ] set_messages = [ Msg('set', mtr, i) for i, mtr in itertools.product( range(-5, 6), [get_motor() for _ in range(5)]) ] read_messages = [ Msg('read', obj) for obj in all_objects if hasattr(obj, 'read') ] trigger_messages = [ Msg('trigger', obj) for obj in all_objects if hasattr(obj, 'trigger') ] stage_messages = [Msg('stage', obj) for obj in all_objects] unstage_messages = [Msg('unstage', obj) for obj in all_objects] # throw random garbage at the open run metadata to see if we can break it openrun_garbage = [ random.sample(gc.get_objects(), random.randint(1, 10)) for _ in range(10) ] openrun_messages = [ Msg('open_run', None, {str(v): v for v in garbage}) for garbage in openrun_garbage ] closerun_messages = [Msg('close_run')] * 10 checkpoint_messages = [Msg('checkpoint')] * 10 clear_checkpoint_messages = [Msg('clear_checkpoint')] * 10 create_messages = ([Msg('create', name='primary')] * 5 + [Msg('create', name=unique_name()) for _ in range(5)]) save_messages = [Msg('save')] * 10 sleep_messages = [ Msg('sleep', None, random.random() * 0.25) for _ in range(10) ] pause_messages = [Msg('pause')] * 10 null_messages = [Msg('null')] * 10 configure_messages = [ Msg('configure', obj, d={}) for obj in all_objects if hasattr(obj, 'configure') ] # compile the list of all messages that we can send at the run engine message_objects = (flyer_messages + set_messages + read_messages + trigger_messages + stage_messages + unstage_messages + openrun_messages + closerun_messages + checkpoint_messages + clear_checkpoint_messages + create_messages + save_messages + sleep_messages + pause_messages + null_messages + configure_messages) print("Using the following messages") pprint(message_objects) RE = setup_test_run_engine() print("I am missing the following types of messages from my list") print( set(RE._command_registry.keys()) - set([msg.command for msg in message_objects])) num_message = 100 num_SIGINT = 10 num_scans = 50 num_shuffled_scans = 50 random.shuffle(message_objects) choices = (['message'] * num_message + # ['sigint'] * num_SIGINT + ['scan'] * num_scans + ['shuffled_scan'] * num_shuffled_scans) sigints = [('interrupt', ['paused', 'idle'], interrupt_func), ('kill', ['idle'], kill_func), ('spam SIGINT', ['idle'], spam_SIGINT), ('random SIGINTs', ['idle', 'paused'], randomly_SIGINT_in_the_future)] scan_generator_funcs = get_scan_generators() shufflable_scans = get_shuffleable_scan_generators() msg_seq = [] count = 0 while count < 500: name = random.choice(choices) if name == 'message': try: # grab a random sequence of messages msg = random.choice(message_objects) print(msg.command) msg_seq.append(msg.command) try: RE([msg]) except RunEngineInterrupted: pass if msg.command == 'pause': RE.resume() assert RE.state == 'idle' except IllegalMessageSequence as err: print(err) elif name == 'scan': scan_gen_func = random.choice(scan_generator_funcs) print("Running scan: {}" "".format(scan_gen_func.__code__.co_name)) scan_generator = make_scan_from_gen_func(scan_gen_func) try: RE(scan_generator) except RunEngineInterrupted: pass elif name == 'shuffled_scan': scan_gen_func = random.choice(shufflable_scans) print("Running shuffled scan: {}" "".format(scan_gen_func.__code__.co_name)) shuffled_scan = make_scan_from_gen_func(scan_gen_func) try: RE(shuffled_scan) except RunEngineInterrupted: pass elif name == 'sigint': sigint_type, allowed_states, func = random.choice(sigints) print(sigint_type) msg_seq.append(sigint_type) # TODO Figure out how to verify that the RunEngine is in # the desired state after this call_later executes loop.call_later(1, func) else: raise NotImplementedError("{} is not implemented".format(name)) count += 1 if count % 100 == 0: print('processed %s messages' % count) # Make sure the Run Engine is in a reasonable state if RE.state == 'idle': # all is well pass elif RE.state == 'running': # uh oh raise RuntimeError("Somehow the RunEngine thinks it is running") # RE.abort() elif RE.state == 'paused': RE.abort() else: # no way we can get here raise RuntimeError("How is the run engine even in this state? {}" "".format(RE.state)) try: # make sure we are idle before the next iteration assert RE.state == 'idle' # there is a chance that a sigint will get thrown between the end # of the above if/else block and this assert... except AssertionError: if RE.state == 'paused': RE.abort() assert RE.state == 'idle' print('%s actions were thrown at the RunEngine' % count) print("Fuzz testing completed successfully") print("Actions taken in the following order") pprint(msg_seq) print("Fuzz testing did not use the following messages") pprint(set(RE._command_registry.keys()) - set(msg_seq))
def run_fuzz(): # create 10 different flyers with corresponding kickoff and collect # messages flyer_messages = [msg for _ in range(10) for msg in kickoff_and_collect(block=random.random()>0.5, magic=random.random()>0.5)] set_messages = [Msg('set', mtr, i) for i, mtr in itertools.product(range(-5, 6), [get_motor() for _ in range(5)])] read_messages = [Msg('read', obj) for obj in all_objects if hasattr(obj, 'read')] trigger_messages = [Msg('trigger', obj) for obj in all_objects if hasattr(obj, 'trigger')] stage_messages = [Msg('stage', obj) for obj in all_objects] unstage_messages = [Msg('unstage', obj) for obj in all_objects] # throw random garbage at the open run metadata to see if we can break it openrun_garbage = [random.sample(gc.get_objects(), random.randint(1, 10)) for _ in range(10)] openrun_messages = [Msg('open_run', None, {str(v): v for v in garbage}) for garbage in openrun_garbage] closerun_messages = [Msg('close_run')] * 10 checkpoint_messages = [Msg('checkpoint')] * 10 clear_checkpoint_messages = [Msg('clear_checkpoint')] * 10 create_messages = ([Msg('create')] * 5 + [Msg('create', name=unique_name()) for _ in range(5)]) save_messages = [Msg('save')] * 10 sleep_messages = [Msg('sleep', None, random.random() * 0.25) for _ in range(10)] pause_messages = [Msg('pause')] * 10 null_messages = [Msg('null')] * 10 configure_messages = [Msg('configure', obj, d={}) for obj in all_objects if hasattr(obj, 'configure')] # compile the list of all messages that we can send at the run engine message_objects = (flyer_messages + set_messages + read_messages + trigger_messages + stage_messages + unstage_messages + openrun_messages + closerun_messages + checkpoint_messages + clear_checkpoint_messages + create_messages + save_messages + sleep_messages + pause_messages + null_messages + configure_messages) print("Using the following messages") pprint(message_objects) RE = setup_test_run_engine() print("I am missing the following types of messages from my list") print(set(RE._command_registry.keys()) - set([msg.command for msg in message_objects])) num_message = 100 num_SIGINT = 8 num_scans = 50 num_shuffled_scans = 50 random.shuffle(message_objects) choices = (['message'] * num_message + ['sigint'] * num_SIGINT + ['scan'] * num_scans + ['shuffled_scan'] * num_shuffled_scans) sigints = [ ('interrupt', ['paused', 'idle'], interrupt_func), ('kill', ['idle'], kill_func), ('spam SIGINT', ['idle'], spam_SIGINT), ('random SIGINTs', ['idle', 'paused'], randomly_SIGINT_in_the_future) ] scan_generator_funcs = get_scan_generators() shufflable_scans = get_shuffleable_scan_generators() msg_seq = [] count = 0 while count < 500: name = random.choice(choices) if name == 'message': try: # grab a random sequence of messages msg = random.choice(message_objects) print(msg.command) msg_seq.append(msg.command) RE([msg]) if msg.command == 'pause': RE.resume() assert RE.state == 'idle' except IllegalMessageSequence as err: print(err) elif name == 'scan': scan_gen_func = random.choice(scan_generator_funcs) print("Running scan: {}" "".format(scan_gen_func.__code__.co_name)) scan_generator = make_scan_from_gen_func(scan_gen_func) RE(scan_generator) elif name == 'shuffled_scan': scan_gen_func = random.choice(shufflable_scans) print("Running shuffled scan: {}" "".format(scan_gen_func.__code__.co_name)) shuffled_scan = make_scan_from_gen_func(scan_gen_func) RE(shuffled_scan) elif name == 'sigint': sigint_type, allowed_states, func = random.choice(sigints) print(sigint_type) msg_seq.append(sigint_type) #TODO Figure out how to verify that the RunEngine is in the desired state after this call_later executes loop.call_later(1, func) else: raise NotImplementedError("{} is not implemented".format(name)) count += 1 if count % 100 == 0: print('processed %s messages' % count) # Make sure the Run Engine is in a reasonable state if RE.state == 'idle': # all is well pass elif RE.state == 'running': # uh oh raise RuntimeError("Somehow the RunEngine thinks it is running") # RE.abort() elif RE.state == 'paused': RE.abort() else: # no way we can get here raise RuntimeError("How is the run engine even in this state? {}" "".format(RE.state)) try: # make sure we are idle before the next iteration assert RE.state == 'idle' # there is a chance that a sigint will get thrown between the end # of the above if/else block and this assert... except AssertionError: if RE.state == 'paused': RE.abort() assert RE.state == 'idle' print('%s actions were thrown at the RunEngine' % count) print("Fuzz testing completed successfully") print("Actions taken in the following order") pprint(msg_seq) print("Fuzz testing did not use the following messages") pprint(set(RE._command_registry.keys()) - set(msg_seq))