class TestCounterDemoSystem(unittest.TestCase): def setUp(self): self.process = Process("proc") parts = [call_with_params(CounterPart, name="cpart")] self.controller = Controller(self.process, "counting", parts) self.process.start() def tearDown(self): self.process.stop(timeout=1) def test_counter_subscribe(self): q = Queue() sub = Subscribe(id=20, path=["counting", "counter"], delta=False, callback=q.put) self.controller.handle_request(sub) response = q.get(timeout=1.0) self.assertIsInstance(response, Update) assert response.id == 20 assert response.value["typeid"] == "epics:nt/NTScalar:1.0" assert response.value["value"] == 0 post = Post(id=21, path=["counting", "increment"], callback=q.put) self.controller.handle_request(post) response = q.get(timeout=1) self.assertIsInstance(response, Update) assert response.id == 20 assert response.value["value"] == 1 response = q.get(timeout=1) self.assertIsInstance(response, Return) assert response.id == 21 assert response.value == None with self.assertRaises(TimeoutError): q.get(timeout=0.05)
class TestCompoundPart(ChildTestCase): def setUp(self): self.process = Process("Process") self.context = Context(self.process) child = self.create_child_block(compound_motor_block, self.process, mri="my_mri", prefix="PV:PRE") self.set_attributes(child, maxVelocity=5.0, accelerationTime=0.5, readback=12.3, offset=4.5, resolution=0.001, cs="CS_PORT,B") self.o = MotorPart(name="scan", mri="my_mri") self.process.start() def tearDown(self): self.process.stop(timeout=1) def test_report(self): returns = self.o.report_status(self.context) assert returns.cs_axis == "B" assert returns.cs_port == "CS_PORT" assert returns.acceleration == 10.0 assert returns.resolution == 0.001 assert returns.offset == 4.5 assert returns.max_velocity == 5.0 assert returns.current_position == 12.3 assert returns.scannable == "scan"
class TestCounterPart(unittest.TestCase): def setUp(self): self.p = Process("proc") c = BasicController("mri") c.add_part(CounterPart(name='counting')) self.p.add_controller(c) self.p.start() self.b = self.p.block_view("mri") def tearDown(self): self.p.stop() def test_increment_increments(self): assert 0 == self.b.counter.value self.b.increment() assert 1 == self.b.counter.value self.b.increment() assert 2 == self.b.counter.value def test_reset_sets_zero(self): self.b.counter.put_value(1234) assert 1234 == self.b.counter.value self.b.zero() assert 0 == self.b.counter.value
class TestCSPart(ChildTestCase): def setUp(self): self.process = Process("Process") self.child = self.create_child_block(cs_block, self.process, mri="PMAC:CS1", pv_prefix="PV:PRE") self.set_attributes(self.child, port="PMAC2CS1") c = ManagerController("PMAC", "/tmp") c.add_part(CSPart(mri="PMAC:CS1", cs=1)) self.process.add_controller(c) self.process.start() self.b = c.block_view() def tearDown(self): self.process.stop(timeout=1) def test_init(self): assert "moveCS1" in self.b def test_move(self): self.mock_when_value_matches(self.child) # Move time is converted into milliseconds move_time = 2.3 expected_move_time = move_time * 1000.0 self.b.moveCS1(a=32, c=19.1, moveTime=move_time) assert self.child.handled_requests.mock_calls == [ call.put("deferMoves", True), call.put("csMoveTime", expected_move_time), call.put("demandA", 32), call.put("demandC", 19.1), call.when_value_matches("demandA", 32, None), call.when_value_matches("demandC", 19.1, None), call.put("deferMoves", False), ]
class TestCompoundMotorCSPart(unittest.TestCase): @patch("malcolm.modules.ca.util.catools") def setUp(self, catools): self.catools = catools catools.caget.side_effect = [[castr("@asyn(BRICK1CS1,2)")]] self.process = Process("proc") self.o = CompoundMotorCSPart("cs", "PV:PRE.OUT") c = StatefulController("mri") c.add_part(self.o) self.process.add_controller(c) self.b = self.process.block_view("mri") self.process.start() self.addCleanup(self.process.stop) def test_init(self): self.catools.caget.assert_called_once_with( ["PV:PRE.OUT"], format=self.catools.FORMAT_CTRL) assert list( self.b) == ['meta', 'health', 'state', 'disable', 'reset', 'cs'] assert self.b.cs.value == "BRICK1CS1,B" def test_update_good(self): update = castr("@asyn(BRICK1CS1, 3)") self.o._update_value(update) assert self.b.cs.value == "BRICK1CS1,C" def test_update_bad(self): update = castr("@asyn(BRICK1CS1, 3)") update.ok = False self.o._update_value(update) assert self.b.cs.value == "" assert self.b.cs.alarm.severity == AlarmSeverity.INVALID_ALARM
class TestMotorPreMovePart(ChildTestCase): def setUp(self): self.process = Process("test_process") self.context = Context(self.process) # Create a raw motor mock to handle axis request self.child = self.create_child_block(raw_motor_block, self.process, mri="BS", pv_prefix="PV:PRE") # Add Beam Selector object self.o = MotorPreMovePart(name="MotorPreMovePart", mri="BS", demand=50) controller = RunnableController("SCAN", "/tmp") controller.add_part(self.o) self.process.add_controller(controller) self.process.start() def tearDown(self): del self.context self.process.stop(timeout=1) def test_bs(self): b = self.context.block_view("SCAN") generator = CompoundGenerator([LineGenerator("x", "mm", 0, 1, 10)], [], [], 0.1) b.configure(generator) self.o.on_configure(self.context) assert self.child.handled_requests.mock_calls == [ call.put("demand", 50) ]
def test_caput_status_pv_message(self, catools): p = self.create_part( dict( name="mname", description="desc", pv="pv", status_pv="spv", good_status="All Good", message_pv="mpv", ) ) catools.caget.return_value = [caint(4)] c = StatefulController("mri") c.add_part(p) proc = Process("proc") proc.add_controller(c) proc.start() self.addCleanup(proc.stop) b = proc.block_view("mri") self.make_camonitor_return(catools, "No Good") catools.caget.return_value = "Bad things happened" with self.assertRaises(AssertionError) as cm: b.mname() assert ( str(cm.exception) == "Status No Good: Bad things happened: " "while performing 'caput pv 1'" )
class TestSystemWSCommsServerOnly(unittest.TestCase): socket = 8881 def setUp(self): self.sf = SyncFactory("sync") self.process = Process("proc", self.sf) part = HelloPart(self.process, None) DefaultController("hello", self.process, parts={"hello": part}) WebsocketServerComms(self.process, dict(port=self.socket)) self.process.start() def tearDown(self): self.process.stop() @gen.coroutine def send_message(self): conn = yield websocket_connect("ws://localhost:%s/ws" % self.socket) req = dict(type="malcolm:core/Post:1.0", id=0, endpoint=["hello", "say_hello"], parameters=dict(name="me")) conn.write_message(json.dumps(req)) resp = yield conn.read_message() resp = json.loads(resp) self.assertEqual( resp, dict(id=0, type="malcolm:core/Return:1.0", value=dict(greeting="Hello me"))) conn.close() def test_server_and_simple_client(self): self.send_message()
class TestHelloPart(unittest.TestCase): def setUp(self): self.p = Process("proc") c = BasicController("mri") c.add_part(HelloPart(name='block')) self.p.add_controller(c) self.p.start() def tearDown(self): self.p.stop() def test_say_hello(self): b = self.p.block_view("mri") expected = "Hello test_name" response = b.greet("test_name", 0) assert expected == response def test_method_meta(self): b = self.p.block_view("mri") method = b.greet assert list(method.to_dict()) == [ 'typeid', 'takes', 'defaults', 'description', 'tags', 'writeable', 'label', 'returns' ] assert method.defaults == dict(sleep=0.0) assert list(method.takes["elements"]) == ["name", "sleep"] assert list(method.returns["elements"]) == ["return"] assert method.tags == ["method:return:unpacked"] assert method.writeable
class TestHelloBlock(unittest.TestCase): def setUp(self): self.p = Process("proc") for c in hello_block("mri"): self.p.add_controller(c) self.p.start() def tearDown(self): self.p.stop() def test_say_hello(self): b = self.p.block_view("mri") expected = "Hello test_name" response = b.greet("test_name", 0) assert expected == response def test_method_meta(self): b = self.p.block_view("mri") method = b.greet.meta assert list(method.to_dict()) == [ "typeid", "takes", "defaults", "description", "tags", "writeable", "label", "returns", ] assert method.defaults == dict(sleep=0.0) assert list(method.takes["elements"]) == ["name", "sleep"] assert list(method.returns["elements"]) == ["return"] assert method.tags == ["method:return:unpacked"] assert method.writeable
class TestLabelPart(unittest.TestCase): def setUp(self): self.o = call_with_params(LabelPart, initialValue="My label", group="mygroup") self.p = Process("proc") self.c = Controller(self.p, "mri", [self.o]) self.p.add_controller("mri", self.c) self.p.start() self.b = self.c.block_view() def tearDown(self): self.p.stop(1) def test_init(self): assert self.o.name == "label" assert self.o.attr.value == "My label" assert self.o.attr.meta.tags == ("widget:textinput", "config", "group:mygroup") assert self.b.meta.label == "My label" def test_setter(self): self.b.label.put_value("My label2") assert self.b.label.value == "My label2" assert self.b.meta.label == "My label2"
def prepare_locals(args): from malcolm.core import Process from malcolm.yamlutil import make_include_creator if args.yaml: proc_name = os.path.basename(args.yaml).split(".")[-2] proc = Process(proc_name) controllers, parts = make_include_creator(args.yaml)() assert not parts, "%s defines parts" % (args.yaml, ) for controller in controllers: proc.add_controller(controller) proc_name = "%s - imalcolm" % proc_name else: proc = Process("Process") proc_name = "imalcolm" # set terminal title sys.stdout.write("\x1b]0;%s\x07" % proc_name) if args.client: if args.client.startswith("ws://"): from malcolm.modules.web.controllers import WebsocketClientComms hostname, port = args.client[5:].split(":") comms = WebsocketClientComms(mri="%s:%s" % (hostname, port), hostname=hostname, port=int(port)) elif args.client == "pva": from malcolm.modules.pva.controllers import PvaClientComms comms = PvaClientComms(mri="pva") else: raise ValueError("Don't know how to create client to %s" % args.client) proc.add_controller(comms) proc.start(timeout=60) return proc
class TestUnrollingPartInitialVisibilityFalse(unittest.TestCase): def setUp(self): self.o = UnrollingPart(name="Unroll", mri="mri", initial_visibility=False) self.process = Process("proc") self.process.start() self.addCleanup(self.process.stop, 2) self.config_dir = tmp_dir("config_dir") c = RunnableController("mri", self.config_dir.value) c.add_part(self.o) self.process.add_controller(c) self.b = c.block_view() def tearDown(self): shutil.rmtree(self.config_dir.value) def test_2d_no_changes_when_initial_visibility_is_False(self): generator_before = make_generator() results = self.b.validate(generator_before, ["x", "y"]) generator_after = results["generator"] generator_before.prepare() generator_after.prepare() assert generator_before == generator_after assert len(generator_after.dimensions) == 2 assert len(generator_after.excluders) == 0 def test_on_validate_returns_None_when_not_visible(self): generator_before = make_generator() assert self.o.visible is False results = self.o.on_validate(generator_before, ["x", "y"]) assert results is None
class TestSystemPVACommsServerAndClient(unittest.TestCase): def setUp(self): self.mp_q = multiprocessing.Queue() self.mp = multiprocessing.Process(target=p1, args=(self.mp_q, )) self.mp.start() from malcolm.core import Process, call_with_params from malcolm.blocks.pva import pva_client_block self.process2 = Process("proc2") self.client = call_with_params(pva_client_block, self.process2, mri="client") self.process2.start() def tearDown(self): self.process2.stop(timeout=1) self.mp_q.put(None) self.mp.join() def s_server_hello_with_malcolm_client(self): from malcolm.core import call_with_params, Context, ResponseError from malcolm.blocks.builtin import proxy_block call_with_params(proxy_block, self.process2, mri="hello", comms="client") context = Context(self.process2) context.when_matches(["hello", "health", "value"], "OK", timeout=2) block2 = self.process2.block_view("hello") ret = block2.greet(name="me2") assert ret == dict(greeting="Hello me2") with self.assertRaises(ResponseError): block2.error()
class TestCSOutlinksPart(unittest.TestCase): @patch("malcolm.modules.ca.util.catools") def setUp(self, catools): self.catools = catools catools.caget.side_effect = [[castr("BRICK1CS1")]] self.process = Process("proc") self.o = CSSourcePortsPart("cs", "PV:PRE:Port") c = StatefulController("mri") c.add_part(self.o) self.process.add_controller(c) self.b = self.process.block_view("mri") self.process.start() self.addCleanup(self.process.stop) def test_init(self): self.catools.caget.assert_called_once_with( ["PV:PRE:Port"], datatype=self.catools.DBR_STRING, format=self.catools.FORMAT_CTRL) assert list(self.b) == [ 'meta', 'health', 'state', 'disable', 'reset', 'cs', 'a', 'b', 'c', 'u', 'v', 'w', 'x', 'y', 'z', 'i' ] assert self.b.cs.value == "BRICK1CS1" assert self.b.a.value == "" assert self.b.a.meta.tags == ["sourcePort:motor:BRICK1CS1,A"] assert self.b.v.value == "" assert self.b.v.meta.tags == ["sourcePort:motor:BRICK1CS1,V"] assert self.b.i.value == "" assert self.b.i.meta.tags == ["sourcePort:motor:BRICK1CS1,I"]
class TestProcessController(unittest.TestCase): prefix = f"unitTest:{floor(time.time()).__repr__()[:-2]}" def setUp(self): self.config_dir = tmp_dir("config_dir") self.process = Process("proc") self.o = ProcessController("MyMRI", self.prefix, self.config_dir.value) self.process.add_controller(self.o) self.process.start() self.b = self.process.block_view("MyMRI") def tearDown(self): self.process.stop(timeout=2) shutil.rmtree(self.config_dir.value) def test_sets_stats(self): # In unit tests, this depends on where the test-runner is run from assert self.b.pymalcolmVer.value in ["work", __version__] hostname = os.uname()[1] hostname = hostname if len(hostname) < 39 else hostname[:35] + "..." assert self.b.hostname.value == hostname def test_starts_ioc(self): cothread.Sleep(5) assert catools.caget(self.prefix + ":PYMALCOLM:VER") in ["work", __version__] def test_ioc_ticks(self): cothread.Sleep(5) uptime = catools.caget(self.prefix + ":UPTIME:RAW") assert uptime >= 0 time.sleep(5) assert catools.caget(self.prefix + ":UPTIME:RAW") >= uptime + 5
class TestRawMotorPart(ChildTestCase): def setUp(self): self.process = Process("Process") self.context = Context(self.process) child = self.create_child_block(raw_motor_block, self.process, mri="mri", prefix="PV:PRE", motorPrefix="MOT:PRE", scannable="scan") child.parts["maxVelocity"].attr.set_value(5.0) child.parts["accelerationTime"].attr.set_value(0.5) child.parts["readback"].attr.set_value(12.3) child.parts["offset"].attr.set_value(4.5) child.parts["resolution"].attr.set_value(0.001) child.parts["csPort"].attr.set_value("CS1") child.parts["csAxis"].attr.set_value("Y") self.o = call_with_params(RawMotorPart, name="part", mri="mri") list(self.o.create_attribute_models()) self.process.start() def tearDown(self): del self.context self.process.stop(timeout=1) def test_report(self): returns = self.o.report_cs_info(self.context)[0] assert returns.cs_axis == "Y" assert returns.cs_port == "CS1" assert returns.acceleration == 10.0 assert returns.resolution == 0.001 assert returns.offset == 4.5 assert returns.max_velocity == 5.0 assert returns.current_position == 12.3 assert returns.scannable == "scan"
class TestBasicController(unittest.TestCase): def setUp(self): self.process = Process("proc") self.o = BasicController("MyMRI") self.process.add_controller(self.o) self.process.start() self.b = self.process.block_view("MyMRI") def tearDown(self): self.process.stop(timeout=2) def update_health(self, num, alarm=Alarm.ok): self.o.update_health(num, HealthInfo(alarm)) def test_set_health(self): self.update_health(1, Alarm(severity=AlarmSeverity.MINOR_ALARM)) self.update_health(2, Alarm(severity=AlarmSeverity.MAJOR_ALARM)) assert self.b.health.alarm.severity == AlarmSeverity.MAJOR_ALARM self.update_health(1, Alarm(severity=AlarmSeverity.UNDEFINED_ALARM)) self.update_health(2, Alarm(severity=AlarmSeverity.INVALID_ALARM)) assert self.b.health.alarm.severity == AlarmSeverity.UNDEFINED_ALARM self.update_health(1) self.update_health(2) assert self.o.health.value == "OK"
class TestSimDetectorDriverPart(ChildTestCase): def setUp(self): self.process = Process("Process") self.context = Context(self.process) self.child = self.create_child_block(sim_detector_driver_block, self.process, mri="mri", prefix="prefix") choices = ["Single", "Multiple", "Continuous"] self.child.parts["imageMode"].attr.meta.set_choices(choices) self.o = call_with_params(SimDetectorDriverPart, name="m", mri="mri") list(self.o.create_attribute_models()) self.process.start() def test_report(self): infos = self.o.report_configuration(self.context) assert len(infos) == 2 assert infos[0].value == 0 assert infos[1].rank == 2 def test_validate(self): params = MagicMock() xs = LineGenerator("x", "mm", 0.0, 0.5, 3, alternate=True) ys = LineGenerator("y", "mm", 0.0, 0.1, 2) params.generator = CompoundGenerator([ys, xs], [], [], 0.1) params.generator.prepare() self.o.validate(ANY, ANY, params) def test_configure(self): params = MagicMock() xs = LineGenerator("x", "mm", 0.0, 0.5, 3, alternate=True) ys = LineGenerator("y", "mm", 0.0, 0.1, 2) params.generator = CompoundGenerator([ys, xs], [], [], 0.1) params.generator.prepare() completed_steps = 0 steps_to_do = 6 part_info = ANY self.o.configure(self.context, completed_steps, steps_to_do, part_info, params) assert self.child.handled_requests.mock_calls == [ call.put('arrayCallbacks', True), call.put('arrayCounter', 0), call.put('imageMode', 'Multiple'), call.put('numImages', 6), call.put('exposure', 0.1 - 7e-5) ] def test_run(self): update_completed_steps = MagicMock() self.o.start_future = MagicMock() self.o.done_when_reaches = MagicMock() self.o.completed_offset = 0 self.o.run(self.context, update_completed_steps) assert self.child.handled_requests.mock_calls == [call.post('start')] def test_abort(self): self.o.abort(self.context) assert self.child.handled_requests.mock_calls == [call.post('stop')]
class TestReframePluginPart(ChildTestCase): def setUp(self): self.process = Process("Process") self.context = Context(self.process) self.child = self.create_child_block(reframe_plugin_block, self.process, mri="mri", prefix="prefix") choices = ["Single", "Multiple", "Continuous"] self.child.parts["imageMode"].attr.meta.set_choices(choices) self.o = call_with_params(ReframePluginPart, name="m", mri="mri") list(self.o.create_attribute_models()) self.process.start() def test_report(self): infos = self.o.report_configuration(self.context) assert len(infos) == 2 assert infos[0].value == 0 assert infos[1].rank == 2 def test_validate(self): params = MagicMock() xs = LineGenerator("x", "mm", 0.0, 0.5, 3, alternate=True) ys = LineGenerator("y", "mm", 0.0, 0.1, 2) params.generator = CompoundGenerator([ys, xs], [], [], 0.0002) params.generator.prepare() self.o.validate(ANY, ANY, params) def test_validate_fails(self): params = MagicMock() xs = LineGenerator("x", "mm", 0.0, 0.5, 3, alternate=True) ys = LineGenerator("y", "mm", 0.0, 0.1, 2) params.generator = CompoundGenerator([ys, xs], [], [], 0.00009) params.generator.prepare() with self.assertRaises(AssertionError): self.o.validate(ANY, ANY, params) def test_configure(self): params = MagicMock() xs = LineGenerator("x", "mm", 0.0, 0.5, 3, alternate=True) ys = LineGenerator("y", "mm", 0.0, 0.1, 2) params.generator = CompoundGenerator([ys, xs], [], [], 0.1) params.generator.prepare() completed_steps = 0 steps_to_do = 6 part_info = ANY self.o.configure(self.context, completed_steps, steps_to_do, part_info, params) # Need to wait for the spawned mock start call to run self.o.start_future.result() assert self.child.handled_requests.mock_calls == [ call.put('arrayCallbacks', True), call.put('arrayCounter', 0), call.put('imageMode', 'Multiple'), call.put('numImages', 6), call.put('postCount', 999), call.post('start') ]
class TestProcess(unittest.TestCase): def setUp(self): self.o = Process("proc") self.o.start() def tearDown(self): self.o.stop(timeout=1) def test_init(self): assert self.o.name == "proc" def test_add_controller(self): controller = MagicMock(mri="mri") self.o.add_controller(controller) assert self.o.get_controller("mri") == controller def test_init_controller(self): class InitController(Controller): init = False def on_hook(self, hook): if isinstance(hook, ProcessStartHook): self.init = True c = InitController("mri") self.o.add_controller(c) assert c.init == True def test_publish_controller(self): class PublishController(Controller): published = [] def on_hook(self, hook): if isinstance(hook, ProcessPublishHook): hook(self.do_publish) @add_call_types def do_publish(self, published): # type: (APublished) -> None self.published = published class UnpublishableController(Controller): def on_hook(self, hook): if isinstance(hook, ProcessStartHook): hook(self.on_start) def on_start(self): return UnpublishedInfo(self.mri) c = PublishController("mri") self.o.add_controller(c) assert c.published == ["mri"] self.o.add_controller(Controller(mri="mri2")) assert c.published == ["mri", "mri2"] self.o.add_controller(UnpublishableController("mri3")) assert c.published == ["mri", "mri2"]
class TestCounterDemoSystem(unittest.TestCase): def setUp(self): self.process = Process("proc") self.controller = Controller("counting") self.controller.add_part(CounterPart("cpart")) self.process.add_controller(self.controller) self.process.start() def tearDown(self): self.process.stop(timeout=1) def test_counter_subscribe(self): q = Queue() # Subscribe to the value sub = Subscribe(id=20, path=["counting", "counter"], delta=False) sub.set_callback(q.put) self.controller.handle_request(sub) # Check initial return response = q.get(timeout=1.0) self.assertIsInstance(response, Update) assert response.id == 20 assert response.value["typeid"] == "epics:nt/NTScalar:1.0" assert response.value["value"] == 0 # Post increment() post = Post(id=21, path=["counting", "increment"]) post.set_callback(q.put) self.controller.handle_request(post) # Check the value updates... response = q.get(timeout=1) self.assertIsInstance(response, Update) assert response.id == 20 assert response.value["value"] == 1 # ... then we get the return response = q.get(timeout=1) self.assertIsInstance(response, Return) assert response.id == 21 assert response.value is None # Check we can put too put = Put(id=22, path=["counting", "counter", "value"], value=31) put.set_callback(q.put) self.controller.handle_request(put) # Check the value updates... response = q.get(timeout=1) self.assertIsInstance(response, Update) assert response.id == 20 assert response.value["value"] == 31 # ... then we get the return response = q.get(timeout=1) self.assertIsInstance(response, Return) assert response.id == 22 assert response.value is None # And that there isn't anything else with self.assertRaises(TimeoutError): q.get(timeout=0.05)
class TestOdinDWriterPart(ChildTestCase): def setUp(self): self.process = Process("Process") self.context = Context(self.process) self.child = self.create_child_block(odin_writer_block, self.process, mri="mri", prefix="prefix") self.o = OdinWriterPart(name="m", mri="mri") self.process.start() self.completed_steps = 0 self.steps_to_do = 2000 * 3000 xs = LineGenerator("x", "mm", 0.0, 0.5, 3000, alternate=True) ys = LineGenerator("y", "mm", 0.0, 0.1, 2000) self.generator = CompoundGenerator([ys, xs], [], [], 0.1) self.generator.prepare() def tearDown(self): self.process.stop(timeout=1) def test_configure(self): self.o.configure(self.context, self.completed_steps, self.steps_to_do, {}, generator=self.generator, fileDir='/tmp', fileName='odin.hdf') assert self.child.handled_requests.mock_calls == [ call.put('fileName', 'odin.hdf'), call.put('filePath', '/tmp/'), call.put('numCapture', self.steps_to_do), call.post('start') ] print(self.child.handled_requests.mock_calls) def test_run(self): self.o.configure(self.context, self.completed_steps, self.steps_to_do, {}, generator=self.generator, fileDir='/tmp', fileName='odin.hdf') self.child.handled_requests.reset_mock() self.o.registrar = MagicMock() # run waits for this value self.child.field_registry.get_field("numCaptured").set_value( self.o.done_when_reaches) self.o.run(self.context) assert self.child.handled_requests.mock_calls == [] assert self.o.registrar.report.called_once assert self.o.registrar.report.call_args_list[0][0][0].steps == \ self.steps_to_do
class TestSystemMotionPVA(unittest.TestCase): def setUp(self): self.process = Process("proc") self.config_dir = tmp_dir("config_dir") for controller in motion_block( mri="TESTMOTION", config_dir=self.config_dir.value) + pva_server_block( mri="PVA-SERVER"): self.process.add_controller(controller) self.process.start() self.process2 = Process("proc2") for controller in pva_client_block(mri="PVA-CLIENT") + proxy_block( mri="TESTMOTION", comms="PVA-CLIENT"): self.process2.add_controller(controller) self.process2.start() def tearDown(self): shutil.rmtree(self.config_dir.value) def test_exports(self): block = self.process2.block_view("TESTMOTION") fields = [ "meta", "health", "state", "disable", "reset", "mri", "layout", "design", "exports", "modified", "save", "xMove", "yMove", ] assert list(block) == fields block.xMove(2) block.yMove(3) # Export X t = ExportTable(source=["x.counter"], export=["xValue"]) block.exports.put_value(t) assert list(block) == fields + ["xValue"] assert block.xValue.value == 2.0 # Export Y t = ExportTable(source=["y.counter"], export=["yValue"]) block.exports.put_value(t) assert list(block) == fields + ["yValue"] assert block.yValue.value == 3.0 # Export Nothing t = ExportTable(source=[], export=[]) block.exports.put_value(t) assert list(block) == fields
class TestReframePluginPart(ChildTestCase): def setUp(self): self.process = Process("Process") self.context = Context(self.process) self.child = self.create_child_block( reframe_plugin_block, self.process, mri="mri", prefix="prefix") self.o = ReframePluginPart(name="m", mri="mri") self.process.start() def tearDown(self): self.process.stop(timeout=2) def test_report(self): infos = self.o.report_status() assert infos.rank == 2 def test_validate(self): xs = LineGenerator("x", "mm", 0.0, 0.5, 3, alternate=True) ys = LineGenerator("y", "mm", 0.0, 0.1, 2) generator = CompoundGenerator([ys, xs], [], [], 0.0002) generator.prepare() self.o.validate(generator) def test_validate_fails(self): xs = LineGenerator("x", "mm", 0.0, 0.5, 3, alternate=True) ys = LineGenerator("y", "mm", 0.0, 0.1, 2) generator = CompoundGenerator([ys, xs], [], [], 0.00009) generator.prepare() with self.assertRaises(AssertionError): self.o.validate(generator) def test_configure(self): xs = LineGenerator("x", "mm", 0.0, 0.5, 3, alternate=True) ys = LineGenerator("y", "mm", 0.0, 0.1, 2) generator = CompoundGenerator([ys, xs], [], [], 0.1) generator.prepare() completed_steps = 0 steps_to_do = 6 # We wait to be armed, so set this here self.set_attributes(self.child, acquiring=True) self.o.configure( self.context, completed_steps, steps_to_do, {}, generator) assert self.child.handled_requests.mock_calls == [ call.put('arrayCallbacks', True), call.put('arrayCounter', 0), call.put('imageMode', 'Multiple'), call.put('numImages', 6), call.put('postCount', 999), call.post('start')]
class TestSystemWSCommsServerAndClient(unittest.TestCase): socket = 8883 def setUp(self): self.process = Process("proc") for controller in (hello_block(mri="hello") + counter_block(mri="counter") + web_server_block(mri="server", port=self.socket)): self.process.add_controller(controller) self.process.start() self.process2 = Process("proc2") for controller in ( websocket_client_block(mri="client", port=self.socket) + proxy_block(mri="hello", comms="client") + proxy_block(mri="counter", comms="client")): self.process2.add_controller(controller) self.process2.start() def tearDown(self): self.socket += 1 self.process.stop(timeout=1) self.process2.stop(timeout=1) def test_server_hello_with_malcolm_client(self): block2 = self.process2.block_view("hello") ret = block2.greet("me2") assert ret == "Hello me2" with self.assertRaises(ResponseError): block2.error() def test_server_counter_with_malcolm_client(self): block1 = self.process.block_view("counter") block2 = self.process2.block_view("counter") assert block2.counter.value == 0 block2.increment() assert block2.counter.timeStamp.to_time( ) == block1.counter.timeStamp.to_time() assert block2.counter.value == 1 block2.zero() assert block2.counter.value == 0 assert self.process2.block_view("client").remoteBlocks.value.mri == [ "hello", "counter", "server", ] def test_server_blocks(self): block = self.process.block_view("server") assert block.blocks.value.mri == ["hello", "counter", "server"] assert block.blocks.value.label == ["hello", "counter", "server"] assert block.blocks.meta.writeable is False
class TestBlockModel(unittest.TestCase): @patch("malcolm.gui.guimodel.GuiModel.response_received") def setUp(self, mock_received): # Mock out the signal as it doesn't work without a QApplication running def register(func): self.saved_handle_response = func mock_received.connect.side_effect = register def emit(response): self.saved_handle_response(response) mock_received.emit.side_effect = emit self.process = Process("proc") self.controller = call_with_params(hello_block, self.process, mri="hello_block") self.process.start() self.m = GuiModel(self.process, self.controller.block_view()) def tearDown(self): self.process.stop(timeout=1) def test_init(self): assert self.m.root_item.endpoint == ('hello_block', ) assert len(self.m.root_item.children) == 3 def test_find_item(self): m1, m2 = MagicMock(), MagicMock() BlockItem.items[("foo", "bar")] = m1 BlockItem.items[("foo", )] = m2 item, path = self.m.find_item(('foo', 'bar', 'bat')) assert item == m1 assert path == ['bat'] def test_update_root(self): b_item = self.m.root_item assert [x.endpoint[-1] for x in b_item.children] == (["health", "error", "greet"]) m_item = b_item.children[2] assert m_item.endpoint == ('hello_block', 'greet') assert len(m_item.children) == 2 n_item = m_item.children[0] assert n_item.endpoint == (('hello_block', 'greet', 'takes', 'elements', 'name')) assert n_item.children == [] n_item = m_item.children[1] assert n_item.endpoint == (('hello_block', 'greet', 'takes', 'elements', 'sleep')) assert n_item.children == []
class TestStatefulController(unittest.TestCase): def setUp(self): self.process = Process("proc") self.params = Mock() self.params.mri = "MyMRI" self.params.description = "My description" self.part = MyPart("testpart") self.o = StatefulController(self.process, [self.part], self.params) self.process.add_controller(self.params.mri, self.o) def start_process(self): self.process.start() self.addCleanup(self.stop_process) def stop_process(self): if self.process.started: self.process.stop(timeout=1) def test_process_init(self, ): assert not hasattr(self.part, "started") self.start_process() assert self.part.started def test_process_stop(self): self.start_process() assert not hasattr(self.part, "halted") self.process.stop(timeout=1) assert self.part.halted def test_init(self): assert self.o.state.value == "Disabled" self.start_process() assert self.o.state.value == "Ready" def test_reset_fails_from_ready(self): self.start_process() with self.assertRaises(TypeError): self.o.reset() assert not hasattr(self.part, "reset_done") def test_disable(self): self.start_process() assert not hasattr(self.part, "disable_done") self.o.disable() assert self.part.disable_done assert self.o.state.value == "Disabled" assert not hasattr(self.part, "reset_done") self.o.reset() assert self.part.reset_done assert self.o.state.value == "Ready"
class TestCSOutlinksPart(unittest.TestCase): @patch("malcolm.modules.ca.util.catools") def setUp(self, catools): self.catools = catools catools.caget.side_effect = [[castr("BRICK1CS1")]] self.process = Process("proc") self.o = CSSourcePortsPart("cs", "PV:PRE:Port") c = StatefulController("mri") c.add_part(self.o) self.process.add_controller(c) self.b = self.process.block_view("mri") self.process.start() self.addCleanup(self.process.stop) def test_init(self): self.catools.caget.assert_called_once_with( ["PV:PRE:Port"], datatype=self.catools.DBR_STRING, format=self.catools.FORMAT_CTRL, throw=True, ) assert list(self.b) == [ "meta", "health", "state", "disable", "reset", "cs", "a", "b", "c", "u", "v", "w", "x", "y", "z", "i", ] assert self.b.cs.value == "BRICK1CS1" assert self.b.a.value == "" assert self.b.a.meta.tags == ["sourcePort:motor:BRICK1CS1,A"] assert self.b.v.value == "" assert self.b.v.meta.tags == ["sourcePort:motor:BRICK1CS1,V"] assert self.b.i.value == "" assert self.b.i.meta.tags == ["sourcePort:motor:BRICK1CS1,I"]
class TestCSPart(ChildTestCase): def setUp(self): self.process = Process("Process") self.context = Context(self.process) self.child = self.create_child_block( cs_block, self.process, mri="PMAC:CS1", prefix="PV:PRE") self.set_attributes(self.child, port="CS1") self.o = CSPart(name="pmac", mri="PMAC:CS1") self.process.start() def tearDown(self): self.process.stop(timeout=1) def test_report_status(self): info = self.o.report_status(self.context) assert info.mri == "PMAC:CS1" assert info.port == "CS1"
class TestSystemWSCommsServerAndClient(unittest.TestCase): socket = 8882 def setUp(self): sf = SyncFactory("sync") self.process = Process("proc", sf) Hello(self.process, dict(mri="hello")) Counter(self.process, dict(mri="counter")) self.process.add_comms( WebsocketServerComms(self.process, dict(port=self.socket))) self.process.start() # If we don't wait long enough, sometimes the websocket_connect() # in process2 will hang... time.sleep(0.1) self.process2 = Process("proc2", sf) self.process2.add_comms( WebsocketClientComms(self.process2, dict(hostname="localhost", port=self.socket))) self.process2.start() def tearDown(self): self.socket += 1 self.process.stop() self.process2.stop() def test_server_hello_with_malcolm_client(self): block2 = self.process2.make_client_block("hello") task = Task("task", self.process2) futures = task.when_matches_async(block2["state"], "Ready") task.wait_all(futures, timeout=1) ret = block2.greet("me2") self.assertEqual(ret, dict(greeting="Hello me2")) def test_server_counter_with_malcolm_client(self): block2 = self.process2.make_client_block("counter") task = Task("task", self.process2) futures = task.when_matches_async(block2["state"], "Ready") task.wait_all(futures, timeout=1) self.assertEqual(block2.counter, 0) block2.increment() self.assertEqual(block2.counter, 1)
class TestSystemWSCommsServerOnly(unittest.TestCase): socket = 8881 def setUp(self): self.process = Process("proc", SyncFactory("sync")) Hello(self.process, dict(mri="hello")) self.process.add_comms( WebsocketServerComms(self.process, dict(port=self.socket))) self.process.start() def tearDown(self): self.process.stop() @gen.coroutine def send_message(self): conn = yield websocket_connect("ws://localhost:%s/ws" % self.socket) req = dict( type="malcolm:core/Post:1.0", id=0, endpoint=["hello", "greet"], parameters=dict( name="me" ) ) conn.write_message(json.dumps(req)) resp = yield conn.read_message() resp = json.loads(resp) self.assertEqual(resp, dict( id=0, type="malcolm:core/Return:1.0", value=dict( greeting="Hello me" ) )) conn.close() def test_server_and_simple_client(self): self.send_message()
class TestChildPart(unittest.TestCase): def checkState(self, state): self.assertEqual(self.c.state.value, state) def makeChildBlock(self, blockMri): params = PortsPart.MethodMeta.prepare_input_map(name='Connector') port_part = PortsPart(self.p, params) partName = 'part%s' % blockMri params = DefaultController.MethodMeta.prepare_input_map(mri=blockMri) controller = DefaultController(self.p, [port_part], params) params = ChildPart.MethodMeta.prepare_input_map( mri=blockMri, name=partName) part = ChildPart(self.p, params) return part, controller def setUp(self): self.p = Process('process1', SyncFactory('threading')) self.p1, self.c1 = self.makeChildBlock('child1') self.p2, self.c2 = self.makeChildBlock('child2') self.p3, self.c3 = self.makeChildBlock('child3') # create a root block for the child blocks to reside in parts = [self.p1, self.p2, self.p3] params = RunnableController.MethodMeta.prepare_input_map( mri='mainBlock') self.c = RunnableController(self.p, parts, params) self.b = self.c.block params = ChildPart.MethodMeta.prepare_input_map( mri='mainBlock', name='mainPart') self.part = ChildPart(self.p, params) # Get the parent block into idle state self.p.start() # wait until block is Ready task = Task("block_ready_task", self.p) task.when_matches(self.c.block["state"], sm.IDLE, timeout=1) self.checkState(sm.IDLE) def tearDown(self): self.p.stop() def test_init(self): # check instantiation of object tree via logger names self.assertEqual(self.c._logger.name, 'RunnableController(mainBlock)') self.assertEqual(self.c.parts['partchild1']._logger.name, 'RunnableController(mainBlock).partchild1') self.assertEqual(self.c.parts['partchild2']._logger.name, 'RunnableController(mainBlock).partchild2') self.assertEqual(self.c.parts['partchild3']._logger.name, 'RunnableController(mainBlock).partchild3') self.assertEqual(self.c1.parts['Connector']._logger.name, 'DefaultController(child1).Connector') self.assertEqual(self.c2.parts['Connector']._logger.name, 'DefaultController(child2).Connector') self.assertEqual(self.c3.parts['Connector']._logger.name, 'DefaultController(child3).Connector') self.assertEqual(self.c1.block.inportConnector, '') self.assertEqual(self.c1.block.outportConnector, '') def test_reset(self): # TODO cover the clause 'state == RESETTING' self.c.disable() self.checkState(sm.DISABLED) self.c.reset() self.checkState(sm.IDLE) def test_pre_layout(self): outports = self.p1.pre_layout(None) self.assertEqual(len(outports), 1) def test_layout(self): self.c.edit() self.checkState(sm.EDITABLE) new_layout = Table(self.c.layout.meta) new_layout.name = ["partchild1", "partchild2", "partchild3"] new_layout.mri = ["part1", "part2", "part3"] new_layout.x = [10, 11, 12] new_layout.y = [20, 21, 22] new_layout.visible = [True, True, True] self.b.layout = new_layout self.assertEqual(self.c.parts['partchild1'].x, 10) self.assertEqual(self.c.parts['partchild1'].y, 20) self.assertEqual(self.c.parts['partchild1'].visible, True) self.assertEqual(self.c.parts['partchild2'].x, 11) self.assertEqual(self.c.parts['partchild2'].y, 21) self.assertEqual(self.c.parts['partchild2'].visible, True) self.assertEqual(self.c.parts['partchild3'].x, 12) self.assertEqual(self.c.parts['partchild3'].y, 22) self.assertEqual(self.c.parts['partchild3'].visible, True) new_layout.visible = [True, False, True] self.b.layout= new_layout self.assertEqual(self.c.parts['partchild1'].visible, True) self.assertEqual(self.c.parts['partchild2'].visible, False) self.assertEqual(self.c.parts['partchild3'].visible, True) def test_sever_all_inports(self): self.c1.block.inportConnector = 'Connector' self.c2.block.inportConnector = 'Connector' self.c3.block.inportConnector = 'Connector3' task = Task("Task1" , self.p) self.p1.sever_all_inports(task) task.wait_all([],5) self.assertEqual(self.c1.block.inportConnector, '') self.assertEqual(self.c2.block.inportConnector, 'Connector') self.assertEqual(self.c3.block.inportConnector, 'Connector3') def test_sever_inports_connected_to(self): self.c1.block.inportConnector = 'Connector' self.assertEqual(self.c1.block.inportConnector, 'Connector') task = Task("Task1" , self.p) out_port = {'Connector': 'pos'} self.p1.sever_inports_connected_to(task, out_port) self.assertEqual(self.c1.block.inportConnector, '') def test_get_flowgraph_ports(self): count = len(self.p1._get_flowgraph_ports('out')) self.assertEqual(count, 1) count = len(self.p1._get_flowgraph_ports('in')) self.assertEqual(count, 1)
class TestRunnableController(unittest.TestCase): def checkState(self, state, child=True, parent=True): if child: self.assertEqual(self.b_child.state, state) if parent: self.assertEqual(self.b.state, state) def checkSteps(self, configured, completed, total): self.assertEqual(self.b.configuredSteps, configured) self.assertEqual(self.b.completedSteps, completed) self.assertEqual(self.b.totalSteps, total) self.assertEqual(self.b_child.configuredSteps, configured) self.assertEqual(self.b_child.completedSteps, completed) self.assertEqual(self.b_child.totalSteps, total) def setUp(self): self.maxDiff = 5000 self.p = Process('process1', SyncFactory('threading')) # Make a ticker block to act as our child params = Ticker.MethodMeta.prepare_input_map(mri="childBlock") self.b_child = Ticker(self.p, params)[-1] # Make an empty part for our parent params = Part.MethodMeta.prepare_input_map(name='part1') part1 = Part(self.p, params) # Make a RunnableChildPart to control the ticker params = RunnableChildPart.MethodMeta.prepare_input_map( mri='childBlock', name='part2') part2 = RunnableChildPart(self.p, params) # create a root block for the RunnableController block to reside in params = RunnableController.MethodMeta.prepare_input_map( mri='mainBlock') self.c = RunnableController(self.p, [part1, part2], params) self.b = self.c.block self.sm = self.c.stateMachine # start the process off self.p.start() # wait until block is Ready task = Task("block_ready_task", self.p) task.when_matches(self.b["state"], self.sm.IDLE, timeout=1) self.checkState(self.sm.IDLE) def tearDown(self): self.p.stop() def test_init(self): # the following block attributes should be created by a call to # set_attributes via _set_block_children in __init__ self.assertEqual(self.b['totalSteps'].meta.typeid, 'malcolm:core/NumberMeta:1.0') self.assertEqual(self.b['layout'].meta.typeid, 'malcolm:core/TableMeta:1.0') self.assertEqual(self.b['completedSteps'].meta.typeid, 'malcolm:core/NumberMeta:1.0') self.assertEqual(self.b['configuredSteps'].meta.typeid, 'malcolm:core/NumberMeta:1.0') self.assertEqual(self.b['axesToMove'].meta.typeid, 'malcolm:core/StringArrayMeta:1.0') self.assertEqual(self.b['layoutName'].meta.typeid, 'malcolm:core/StringMeta:1.0') # the following hooks should be created via _find_hooks in __init__ self.assertEqual(self.c.hook_names, { self.c.Reset: "Reset", self.c.Disable: "Disable", self.c.ReportOutports: "ReportOutports", self.c.Layout: "Layout", self.c.Load: "Load", self.c.Save: "Save", self.c.Validate: "Validate", self.c.ReportStatus: "ReportStatus", self.c.Configure: "Configure", self.c.PostConfigure: "PostConfigure", self.c.Run: "Run", self.c.PostRunReady: "PostRunReady", self.c.PostRunIdle: "PostRunIdle", self.c.Seek: "Seek", self.c.Pause: "Pause", self.c.Resume: "Resume", self.c.Abort: "Abort", }) # check instantiation of object tree via logger names self.assertEqual(self.c._logger.name, 'RunnableController(mainBlock)') self.assertEqual(self.c.parts['part1']._logger.name, 'RunnableController(mainBlock).part1') self.assertEqual(self.c.parts['part2']._logger.name, 'RunnableController(mainBlock).part2') def test_edit(self): self.b.edit() self.checkState(self.sm.EDITABLE, child=False) def test_reset(self): self.b.disable() self.checkState(self.sm.DISABLED) self.b.reset() self.checkState(self.sm.IDLE) def test_set_axes_to_move(self): self.c.set_axes_to_move(['y']) self.assertEqual(self.c.axes_to_move.value, ['y']) def test_validate(self): line1 = LineGenerator('y', 'mm', 0, 2, 3) line2 = LineGenerator('x', 'mm', 0, 2, 2) compound = CompoundGenerator([line1, line2], [], []) actual = self.b.validate(generator=compound, axesToMove=['x']) self.assertEqual(actual["generator"], compound) self.assertEqual(actual["axesToMove"], ['x']) def prepare_half_run(self, duration=0.01, exception=0): line1 = LineGenerator('y', 'mm', 0, 2, 3) line2 = LineGenerator('x', 'mm', 0, 2, 2) duration = FixedDurationMutator(duration) compound = CompoundGenerator([line1, line2], [], [duration]) self.b.configure( generator=compound, axesToMove=['x'], exceptionStep=exception) def test_configure_run(self): self.prepare_half_run() self.checkSteps(2, 0, 6) self.checkState(self.sm.READY) self.b.run() self.checkState(self.sm.READY) self.checkSteps(4, 2, 6) self.b.run() self.checkState(self.sm.READY) self.checkSteps(6, 4, 6) self.b.run() self.checkState(self.sm.IDLE) def test_abort(self): self.prepare_half_run() self.b.run() self.b.abort() self.checkState(self.sm.ABORTED) def test_pause_seek_resume(self): self.prepare_half_run() self.checkSteps(configured=2, completed=0, total=6) self.b.run() self.checkState(self.sm.READY) self.checkSteps(4, 2, 6) self.b.pause(completedSteps=1) self.checkState(self.sm.READY) self.checkSteps(2, 1, 6) self.b.run() self.checkSteps(4, 2, 6) self.b.completedSteps = 5 self.checkSteps(6, 5, 6) self.b.run() self.checkState(self.sm.IDLE) def test_resume_in_run(self): self.prepare_half_run(duration=0.5) w = self.p.spawn(self.b.run) time.sleep(0.85) self.b.pause() self.checkState(self.sm.PAUSED) self.checkSteps(2, 1, 6) self.b.resume() # return to PRERUN should continue original run to completion and # READY state then = time.time() w.wait() self.assertAlmostEqual(time.time() - then, 0.5, delta=0.4) self.checkState(self.sm.READY) def test_run_exception(self): self.prepare_half_run(exception=1) with self.assertRaises(ResponseError): self.b.run() self.checkState(self.sm.FAULT) def test_run_stop(self): self.prepare_half_run(duration=0.5) w = self.p.spawn(self.b.run) time.sleep(0.5) self.b.abort() with self.assertRaises(AbortedError): w.get() self.checkState(self.sm.ABORTED)
class TestManagerController(unittest.TestCase): def checkState(self, state, child=True, parent=True): if child: self.assertEqual(self.c_child.state.value, state) if parent: self.assertEqual(self.c.state.value, state) def setUp(self): self.p = Process("process1", SyncFactory("threading")) # create a child ManagerController block params = ManagerController.MethodMeta.prepare_input_map(mri="childBlock") self.c_child = ManagerController(self.p, [], params) self.b_child = self.c_child.block self.sm = self.c_child.stateMachine params = Part.MethodMeta.prepare_input_map(name="part1") part1 = Part(self.p, params) params = {"name": "part2", "mri": "childBlock"} params = ChildPart.MethodMeta.prepare_input_map(**params) part2 = ChildPart(self.p, params) # create a root block for the ManagerController block to reside in parts = [part1, part2] params = {"mri": "mainBlock"} params = ManagerController.MethodMeta.prepare_input_map(**params) self.c = ManagerController(self.p, parts, params) self.b = self.c.block # check that do_initial_reset works asynchronously self.p.start() # wait until block is Ready task = Task("block_ready_task", self.p) task.when_matches(self.b["state"], self.sm.READY, timeout=1) self.checkState(self.sm.READY) def tearDown(self): self.p.stop() def test_init(self): # the following block attributes should be created by a call to # set_attributes via _set_block_children in __init__ self.assertEqual(self.b["layout"].meta.typeid, "malcolm:core/TableMeta:1.0") self.assertEqual(self.b["layoutName"].meta.typeid, "malcolm:core/StringMeta:1.0") # the following hooks should be created via _find_hooks in __init__ self.assertEqual( self.c.hook_names, { self.c.Reset: "Reset", self.c.Disable: "Disable", self.c.Layout: "Layout", self.c.ReportOutports: "ReportOutports", self.c.Load: "Load", self.c.Save: "Save", }, ) # check instantiation of object tree via logger names self.assertEqual(self.c._logger.name, "ManagerController(mainBlock)") self.assertEqual(self.c.parts["part1"]._logger.name, "ManagerController(mainBlock).part1") self.assertEqual(self.c.parts["part2"]._logger.name, "ManagerController(mainBlock).part2") self.assertEqual(self.c_child._logger.name, "ManagerController(childBlock)") def test_edit(self): self.c.edit() # editing only affects one level self.checkState(self.sm.EDITABLE, child=False) self.assertEqual(self.c.revert_structure, self.c._save_to_structure()) def test_edit_exception(self): self.c.edit() with self.assertRaises(Exception): self.c.edit() def test_save(self): self.c.edit() params = {"layoutName": "testSaveLayout"} params = ManagerController.save.MethodMeta.prepare_input_map(**params) self.c.save(params) self.checkState(self.sm.AFTER_RESETTING, child=False) self.assertEqual(self.c.layout_name.value, "testSaveLayout") self.c.edit() params = {"layoutName": None} params = ManagerController.save.MethodMeta.prepare_input_map(**params) self.c.save(params) def test_revert(self): self.c.edit() self.c.revert() self.checkState(self.sm.AFTER_RESETTING, child=False) def test_set_and_load_layout(self): self.c.edit() self.checkState(self.sm.EDITABLE, child=False) new_layout = Table(self.c.layout.meta) new_layout.name = ["part2"] new_layout.mri = ["P45-MRI"] new_layout.x = [10] new_layout.y = [20] new_layout.visible = [True] self.b.layout = new_layout self.assertEqual(self.c.parts["part2"].x, 10) self.assertEqual(self.c.parts["part2"].y, 20) self.assertEqual(self.c.parts["part2"].visible, True) # save the layout, modify and restore it params = {"layoutName": "testSaveLayout"} params = ManagerController.save.MethodMeta.prepare_input_map(**params) self.c.save(params) self.c.edit() new_layout.x = [30] self.b.layout = new_layout self.assertEqual(self.c.parts["part2"].x, 30) self.b.layoutName = "testSaveLayout" self.assertEqual(self.c.parts["part2"].x, 10)
from malcolm.core import SyncFactory, Process, Task from malcolm.blocks.demo import SimulatorPMACManager from scanpointgenerator import LineGenerator, CompoundGenerator, FixedDurationMutator # Make the top level objects sf = SyncFactory("Sync") process = Process("Process", sf) # Make the malcolm object params = SimulatorPMACManager.MethodMeta.prepare_input_map(mriPrefix="TST-PMAC") SimulatorPMACManager(process, params) sim = process.get_block("TST-PMAC") # Start the process process.start() # Wait for everything to settle down task = Task("waiter", process) task.when_matches(sim["state"], "Idle", timeout=10) # Do a test xs = LineGenerator("m1", "mm", -8.0, -12.0, 121, alternate_direction=True) ys = LineGenerator("m2", "mm", -4.0, -6.0, 21) gen = CompoundGenerator([ys, xs], [], [FixedDurationMutator(0.005)]) for i in range(1): sim.configure(gen) sim.run() # process.stop()