def send_subscription(self): endpoints = [self._block] endpoints = endpoints + self.dict_to_path(self._request.toDict()) self.log_debug("Endpoints: %s", endpoints) msg = Subscribe(response_queue=self._server.q, endpoint=endpoints, delta=True) msg.set_id(self._id) self._server.send_to_process(msg)
def test_subscribe_no_data_then_set_data(self): # subscribe request = Subscribe(path=["b", "attr", "value"], delta=False) request.set_callback(Mock()) self.handle_subscribe(request) assert (self.o._tree.children["attr"].children["value"].update_requests ) == ([request]) self.assert_called_with(request.callback, Update(value=None)) request.callback.reset_mock() # set data and check response self.block["attr"] = Dummy() with self.o.changes_squashed: self.block.attr["value"] = 32 self.o.add_squashed_change(["b", "attr", "value"], 32) assert self.block.attr.value == 32 self.assert_called_with(request.callback, Update(value=32)) request.callback.reset_mock() # unsubscribe unsub = Unsubscribe() unsub.set_callback(request.callback) self.handle_unsubscribe(unsub) self.assert_called_with(request.callback, Return(value=None)) request.callback.reset_mock() # notify and check no longer responding with self.o.changes_squashed: self.block.attr["value"] = 33 self.o.add_squashed_change(["b", "attr", "value"], 33) assert self.block.attr.value == 33 request.callback.assert_not_called()
def subscribe(self, attr, callback, *args): """Subscribe to changes in a given attribute and call ``callback(value, *args)`` when it changes Returns: int: an id for the subscription """ assert isinstance(attr, Attribute), \ "Expected Attribute, got %r" % (attr,) endpoint = attr.process_path + ["value"] self.log_debug("Subscribing to %s", endpoint) request = Subscribe(None, self.q, endpoint, False) # If self is in args, then make weak version of it saved_args = [] for arg in args: if arg is self: saved_args.append(weakref.proxy(self)) else: saved_args.append(arg) new_id = self._get_next_id() self._subscriptions[new_id] = (endpoint, callback, args) request.set_id(new_id) self.process.q.put(request) return new_id
def _subscribe_to_block(self, block_name): self.client_comms = self.process.get_client_comms(block_name) assert self.client_comms, \ "Process doesn't know about block %s" % block_name request = Subscribe(None, self, [block_name], delta=True) request.set_id(self.BLOCK_ID) self.client_comms.q.put(request)
def test_subscribe(self): block = MagicMock(to_dict=MagicMock(return_value={ "attr": "value", "inner": { "attr2": "other" } })) p = Process("proc", MagicMock()) sub_1 = Subscribe(MagicMock(), MagicMock(), ["block"], False) sub_1.response_queue.qsize.return_value = 0 sub_2 = Subscribe(MagicMock(), MagicMock(), ["block", "inner"], True) sub_2.response_queue.qsize.return_value = 0 p.q.get = MagicMock(side_effect=[sub_1, sub_2, PROCESS_STOP]) p._handle_block_add(BlockAdd(block, "block", None)) p.recv_loop() self.assertEquals([sub_1, sub_2], list(p._subscriptions.values())) response_1 = sub_1.response_queue.put.call_args[0][0] response_2 = sub_2.response_queue.put.call_args[0][0] self.assertEquals({ "attr": "value", "inner": { "attr2": "other" } }, response_1.value) self.assertEquals([[[], {"attr2": "other"}]], response_2.changes)
def setUp(self): self.context = MagicMock() self.response_queue = MagicMock() self.endpoint = ["BL18I:XSPRESS3", "state", "value"] self.delta = True self.subscribe = Subscribe( self.context, self.response_queue, self.endpoint, delta=self.delta)
def setUp(self): self.callback = MagicMock() self.subscribe = Subscribe(32, ["."]) self.subscribe.set_callback(self.callback) self.subscribes = {self.subscribe.generate_key(): self.subscribe} self.o = Unsubscribe(32) self.o.set_callback(self.callback)
def __init__(self, process, _=None): super(PvaServerComms, self).__init__(process) self.name = "PvaServerComms" self.set_logger_name(self.name) self._lock = RLock() self._current_id = 1 self._root_id = 0 self._blocklist = {} self._cache = Cache() self._server = None self._endpoints = {} self._cb = None self._rpcs = {} self._puts = {} self._dead_rpcs = [] # Create the V4 PVA server object self.create_pva_server() # Add a thread for executing the V4 PVA server self.add_spawn_function(self.start_pva_server) # Set up the subscription for everything (root down) request = Subscribe(None, self.q, [], True) request.set_id(self._root_id) self.process.q.put(request)
def do_initial_reset(self): self.state.set_value("Resetting") self.status.set_value("Waiting for connection...") self.busy.set_value(True) request = Subscribe(None, self, [self.process.name, "remoteBlocks", "value"]) request.set_id(self.REMOTE_BLOCKS_ID) self.process.q.put(request)
def test_unsubscribe(self): # Test that we remove the relevant subscription only and that # updates are no longer sent block = MagicMock(to_dict=MagicMock(return_value={ "attr": "0", "inner": { "attr2": "other" } })) p = Process("proc", MagicMock()) sub_1 = Subscribe(MagicMock(), MagicMock(), ["block"], False) sub_2 = Subscribe(MagicMock(), MagicMock(), ["block"], False) sub_1.set_id(1234) sub_2.set_id(4321) change_1 = BlockChanges([[["block", "attr"], "1"]]) change_2 = BlockChanges([[["block", "attr"], "2"]]) unsub_1 = Unsubscribe(MagicMock(), MagicMock()) unsub_1.set_id(1234) p.q.get = MagicMock(side_effect=[ sub_1, sub_2, change_1, unsub_1, change_2, PROCESS_STOP ]) p._handle_block_add(BlockAdd(block, "block")) p.recv_loop() self.assertEqual([sub_2], p._subscriptions) self.assertEquals(1, len(unsub_1.response_queue.put.call_args_list)) response = unsub_1.response_queue.put.call_args_list[0][0][0] self.assertIsNone(response.value) self.assertIs(unsub_1.context, response.context) sub_1_responses = sub_1.response_queue.put.call_args_list sub_2_responses = sub_2.response_queue.put.call_args_list self.assertEquals(2, len(sub_1_responses)) self.assertEquals(3, len(sub_2_responses))
def test_update_squashing(self): # set some data self.block["attr"] = Dummy() self.block.attr["value"] = 32 self.block["attr2"] = Dummy() self.block.attr2["value"] = "st" # subscribe once and check initial response r1 = Subscribe(path=["b"], delta=True) r1.set_callback(Mock()) r2 = Subscribe(path=["b"]) r2.set_callback(Mock()) self.handle_subscribe(r1) self.handle_subscribe(r2) expected = OrderedDict() expected["attr"] = dict(value=32) expected["attr2"] = dict(value="st") self.assert_called_with(r1.callback, Delta(changes=[[[], expected]])) self.assert_called_with(r2.callback, Update(value=expected)) r1.callback.reset_mock() r2.callback.reset_mock() # squash two changes together with self.o.changes_squashed: self.block.attr["value"] = 33 self.o.add_squashed_change(["b", "attr", "value"], 33) assert self.block.attr.value == 33 self.block.attr2["value"] = "tr" self.o.add_squashed_change(["b", "attr2", "value"], "tr") assert self.block.attr2.value == "tr" self.assert_called_with( r1.callback, Delta( changes=[[["attr", "value"], 33], [["attr2", "value"], "tr"]])) expected["attr"]["value"] = 33 expected["attr2"]["value"] = "tr" self.assert_called_with(r2.callback, Update(value=expected))
def subscribe(self, attr, callback, *args): """Subscribe to changes in a given attribute and call callback with (\*args) when it changes Returns: int: an id for the subscription """ endpoint = [attr.parent.name, attr.name] request = Subscribe(None, self.q, endpoint, False) new_id = self._save_subscription(endpoint, callback, *args) request.set_id(new_id) self.process.q.put(request) return new_id
def test_counter_subscribe(self): sync_factory = SyncFactory("sched") process = Process("proc", sync_factory) b = Counter(process, dict(mri="counting"))[0] process.start() # wait until block is Ready task = Task("counter_ready_task", process) task.when_matches(b["state"], "Ready", timeout=1) q = sync_factory.create_queue() sub = Subscribe(response_queue=q, context="ClientConnection", endpoint=["counting", "counter"], delta=False) process.q.put(sub) resp = q.get(timeout=1) self.assertIsInstance(resp, Update) attr = NTScalar.from_dict(resp.value) self.assertEqual(0, attr.value) post = Post(response_queue=q, context="ClientConnection", endpoint=["counting", "increment"]) process.q.put(post) resp = q.get(timeout=1) self.assertIsInstance(resp, Update) self.assertEqual(resp.value["value"], 1) resp = q.get(timeout=1) self.assertIsInstance(resp, Return) process.stop()
def test_when_matches(self): self.o._q.put(Update(1, "value1")) self.o._q.put(Return(1)) self.o.when_matches(["block", "attr", "value"], "value1", timeout=0.01) assert self.controller.handle_request.call_args_list == [ call(Subscribe(1, ["block", "attr", "value"])), call(Unsubscribe(1)) ]
class TestUnsubscribe(unittest.TestCase): def setUp(self): self.callback = MagicMock() self.subscribe = Subscribe(32, ["."]) self.subscribe.set_callback(self.callback) self.subscribes = {self.subscribe.generate_key(): self.subscribe} self.o = Unsubscribe(32) self.o.set_callback(self.callback) def test_init(self): assert self.o.typeid == "malcolm:core/Unsubscribe:1.0" assert self.o.id == 32 def test_keys_same(self): assert self.subscribes[self.o.generate_key()] == self.subscribe def test_doc(self): assert get_doc_json("unsubscribe") == self.o.to_dict()
def subscribe(self, attr, callback, *args): """Subscribe to changes in a given attribute and call ``callback(value, *args)`` when it changes Returns: int: an id for the subscription """ assert isinstance(attr, Attribute), \ "Expected Attribute, got %r" % (attr,) endpoint = attr.path_relative_to(self.process) + ["value"] self.log_debug("Subscribing to %s", endpoint) request = Subscribe(None, self.q, endpoint, False) new_id = self._save_subscription(endpoint, callback, *args) request.set_id(new_id) self.process.q.put(request) return new_id
def test_when_matches_func(self): self.o._q.put(Update(1, "value1")) self.o._q.put(Return(1)) def f(value): return value.startswith("v") self.o.when_matches(["block", "attr", "value"], f, timeout=0.01) self.assert_handle_request_called_with( Subscribe(1, ["block", "attr", "value"]), Unsubscribe(1))
def test_when_not_matches(self): self.o._q.put(Update(1, "value2")) with self.assertRaises(BadValueError): self.o.when_matches(["block", "attr", "value"], "value1", ["value2"], timeout=0.01) assert self.controller.handle_request.call_args_list == [ call(Subscribe(1, ["block", "attr", "value"])), call(Unsubscribe(1)) ]
def test_when_not_matches(self): self.o._q.put(Update(1, "value2")) with self.assertRaises(BadValueError) as cm: self.o.when_matches(["block", "attr", "value"], "value1", ["value2"], timeout=0.01) assert str(cm.exception) == "Waiting for 'value1', got 'value2'" self.assert_handle_request_called_with( Subscribe(1, ["block", "attr", "value"]), Unsubscribe(1))
def test_2_subscribes(self): # set some data self.block["attr"] = Dummy() self.block.attr["value"] = 32 # subscribe once and check initial response r1 = Subscribe(path=["b", "attr", "value"], delta=False, callback=Mock()) self.handle_subscribe(r1) r1.callback.assert_called_once_with(Update(value=32)) r1.callback.reset_mock() # subscribe again and check initial response r2 = Subscribe(path=["b"], delta=True, callback=Mock()) self.handle_subscribe(r2) r2.callback.assert_called_once_with( Delta(changes=[[[], dict(attr=dict(value=32))]])) r2.callback.reset_mock() # set some data and check only second got called self.block["attr2"] = Dummy() with self.o.changes_squashed: self.block.attr2["value"] = "st" self.o.add_squashed_change(["b", "attr2"], self.block.attr2) r1.callback.assert_not_called() r2.callback.assert_called_once_with( Delta(changes=[[["attr2"], dict(value="st")]])) r2.callback.reset_mock() # delete the first and check calls with self.o.changes_squashed: self.block.data.pop("attr") self.o.add_squashed_change(["b", "attr"]) r1.callback.assert_called_once_with(Update(value=None)) r1.callback.reset_mock() r2.callback.assert_called_once_with(Delta(changes=[[["attr"]]])) r2.callback.reset_mock() # add it again and check updates self.block["attr"] = Dummy() with self.o.changes_squashed: self.block.attr["value"] = 22 self.o.add_squashed_change(["b", "attr"], self.block.attr) r1.callback.assert_called_once_with(Update(value=22)) r2.callback.assert_called_once_with( Delta(changes=[[["attr"], dict(value=22)]]))
def test_send_subscribe_to_server(self): self.PVA = PvaClientComms(self.p) self.PVA.send_to_caller = MagicMock() request = Subscribe(endpoint=["ep1", "ep2"]) request.set_id(1) self.PVA.send_to_server(request) pvaccess.Channel.assert_called_once() self.ch.subscribe.assert_called_once() self.ch.startMonitor.assert_called_once() mon = self.PVA._monitors[1] mon_val = MagicMock() mon_val.toDict = MagicMock(return_value={'typeid': 'malcolm:core/Error:1.0', 'message': 'test error'}) self.PVA.send_to_caller.reset_mock() mon.monitor_update(mon_val) self.PVA.send_to_caller.assert_called_once() self.PVA.send_to_caller.reset_mock() mon_val = MagicMock() mon_val.toDict = MagicMock(return_value={'typeid': 'malcolm:core/Update:1.0'}) mon.monitor_update(mon_val) self.PVA.send_to_caller.assert_called_once()
class TestSubscribe(unittest.TestCase): def setUp(self): self.context = MagicMock() self.response_queue = MagicMock() self.endpoint = ["BL18I:XSPRESS3", "state", "value"] self.delta = True self.subscribe = Subscribe(self.context, self.response_queue, self.endpoint, delta=self.delta) def test_init(self): self.assertEqual(self.context, self.subscribe.context) self.assertEqual(self.response_queue, self.subscribe.response_queue) self.assertEqual(self.endpoint, self.subscribe.endpoint) self.assertEqual(self.delta, self.subscribe.delta) self.assertEqual("malcolm:core/Subscribe:1.0", self.subscribe.typeid) def test_respond_with_update(self): value = MagicMock() self.subscribe.respond_with_update(value) call_arg = self.response_queue.put.call_args_list[0][0][0].to_dict() expected_response = Update(self.subscribe.id, self.subscribe.context, value=value).to_dict() self.assertEqual(call_arg, expected_response) def test_respond_with_delta(self): changes = [[["path"], "value"]] self.subscribe.respond_with_delta(changes) call_arg = self.response_queue.put.call_args_list[0][0][0].to_dict() expected_response = Delta(self.subscribe.id, self.subscribe.context, changes=changes).to_dict() self.assertEqual(call_arg, expected_response) def test_setters(self): self.subscribe.set_endpoint(["BL18I:XSPRESS3", "state", "value2"]) self.assertEquals(["BL18I:XSPRESS3", "state", "value2"], self.subscribe.endpoint) self.subscribe.set_delta(False) self.assertFalse(self.subscribe.delta)
class TestSubscribe(unittest.TestCase): def setUp(self): self.callback = MagicMock() self.path = ["BL18I:XSPRESS3"] self.delta = True self.o = Subscribe(11, self.path, self.delta) self.o.set_callback(self.callback) def test_init(self): assert self.o.typeid == "malcolm:core/Subscribe:1.0" assert self.o.id == 11 assert self.o.callback == self.callback assert self.path == self.o.path assert self.delta == self.o.delta def test_respond_with_update(self): cb, response = self.o.update_response(value=5) assert cb == self.callback assert response.to_dict() == Update(id=11, value=5).to_dict() def test_respond_with_delta(self): changes = [[["path"], "value"]] cb, response = self.o.delta_response(changes) assert cb == self.callback assert response.to_dict() == Delta(id=11, changes=changes).to_dict() def test_setters(self): self.o.path = ["BL18I:XSPRESS3", "state", "value"] self.o.id = 19 d = self.o.to_dict(dict_cls=OrderedDict) del d["delta"] assert get_doc_json("subscribe_xspress3_state_value") == d def test_doc(self): assert get_doc_json("subscribe_xspress3") == self.o.to_dict()
def test_partial_structure_subscriptions(self): block_1 = MagicMock( to_dict=MagicMock( return_value={"attr": "value", "inner": {"attr2": "value"}})) block_2 = MagicMock( to_dict=MagicMock(return_value={"attr": "value"})) sub_1 = Subscribe(None, MagicMock(), ["block_1", "inner"], delta=False) sub_1.set_id(1) sub_1.response_queue.qsize.return_value = 0 sub_2 = Subscribe(None, MagicMock(), ["block_1"], delta=True) sub_2.set_id(2) sub_2.response_queue.qsize.return_value = 0 sub_3 = Subscribe(None, MagicMock(), ["block_1", "inner", "attr2"], delta=False) sub_3.set_id(3) sub_3.response_queue.qsize.return_value = 0 changes_1 = [[["block_1", "inner", "attr2"], "new_value"], [["block_1", "attr"], "new_value"]] changes_2 = [[["block_2", "attr"], "block_2_value"]] request_1 = BlockChanges(changes_1) request_2 = BlockChanges(changes_2) p = Process("proc", MagicMock()) p.q.get = MagicMock(side_effect=[ sub_1, sub_2, sub_3, request_1, request_2, PROCESS_STOP]) p._handle_block_add(BlockAdd(block_1, "block_1", None)) p._handle_block_add(BlockAdd(block_2, "block_2", None)) p.recv_loop() response_1 = sub_1.response_queue.put.call_args_list[1][0][0]["value"] self.assertEquals({"attr2": "new_value"}, response_1) response_2 = sub_2.response_queue.put.call_args_list[1][0][0]["changes"] self.assertEquals([[["inner", "attr2"], "new_value"], [["attr"], "new_value"]], response_2) response_3 = sub_3.response_queue.put.call_args_list[1][0][0]["value"] self.assertEquals("new_value", response_3)
def test_send_subscribe_to_server(self): self.PVA = PvaClientComms(self.p) self.PVA.send_to_caller = MagicMock() request = Subscribe(endpoint=["ep1", "ep2"]) request.set_id(1) self.PVA.send_to_server(request) pvaccess.Channel.assert_called_once() self.ch.subscribe.assert_called_once() self.ch.startMonitor.assert_called_once() mon = self.PVA._monitors[1] mon_val = MagicMock() mon_val.toDict = MagicMock(return_value={ 'typeid': 'malcolm:core/Error:1.0', 'message': 'test error' }) self.PVA.send_to_caller.reset_mock() mon.monitor_update(mon_val) self.PVA.send_to_caller.assert_called_once() self.PVA.send_to_caller.reset_mock() mon_val = MagicMock() mon_val.toDict = MagicMock( return_value={'typeid': 'malcolm:core/Update:1.0'}) mon.monitor_update(mon_val) self.PVA.send_to_caller.assert_called_once()
class TestSubscribe(unittest.TestCase): def setUp(self): self.context = MagicMock() self.response_queue = MagicMock() self.response_queue.qsize.return_value = 0 self.endpoint = ["BL18I:XSPRESS3", "state", "value"] self.delta = True self.subscribe = Subscribe( self.context, self.response_queue, self.endpoint, delta=self.delta) def test_init(self): self.assertEqual(self.context, self.subscribe.context) self.assertEqual(self.response_queue, self.subscribe.response_queue) self.assertEqual(self.endpoint, self.subscribe.endpoint) self.assertEqual(self.delta, self.subscribe.delta) self.assertEqual("malcolm:core/Subscribe:1.0", self.subscribe.typeid) def test_respond_with_update(self): value = MagicMock() self.subscribe.respond_with_update(value) call_arg = self.response_queue.put.call_args_list[0][0][0].to_dict() expected_response = Update(self.subscribe.id, self.subscribe.context, value=value).to_dict() self.assertEqual(call_arg, expected_response) def test_respond_with_delta(self): changes = [[["path"], "value"]] self.subscribe.respond_with_delta(changes) call_arg = self.response_queue.put.call_args_list[0][0][0].to_dict() expected_response = Delta(self.subscribe.id, self.subscribe.context, changes=changes).to_dict() self.assertEqual(call_arg, expected_response) def test_setters(self): self.subscribe.set_endpoint(["BL18I:XSPRESS3", "state", "value2"]) self.assertEquals(["BL18I:XSPRESS3", "state", "value2"], self.subscribe.endpoint) self.subscribe.set_delta(False) self.assertFalse(self.subscribe.delta)
def __init__(self, process, _=None): super(PvaServerComms, self).__init__(process) self.name = "PvaServerComms" self.set_logger_name(self.name) self._lock = RLock() self._current_id = 1 self._root_id = 0 self._local_block_list = {} self._local_block_id = self._get_unique_id() self._remote_block_list = {} self._remote_block_id = self._get_unique_id() self._server = None self._endpoints = {} self._cb = None self._gets = {} self._rpcs = {} self._puts = {} self._monitors = {} self._dead_rpcs = [] # Create the V4 PVA server object self.create_pva_server() # Add a thread for executing the V4 PVA server self.add_spawn_function(self.start_pva_server) self.log_debug("Process name: %s", process.name) # Set up the subscription for local blocks request = Subscribe(None, self.q, [process.name, 'blocks', 'value'], False) request.set_id(self._local_block_id) self.process.q.put(request) # Set up the subscription for remote blocks request = Subscribe(None, self.q, [process.name, 'remoteBlocks', 'value'], False) request.set_id(self._remote_block_id) self.process.q.put(request)
def test_subscribe(self): cb = MagicMock() f = self.o.subscribe(["block", "attr", "value"], cb, self.o, "arg2") self.assert_handle_request_called_with( Subscribe(1, ["block", "attr", "value"])) self.o._q.put(Update(1, "value1")) with self.assertRaises(TimeoutError): self.o.wait_all_futures(f, 0.01) cb.assert_called_once_with("value1", ANY, "arg2") # since args = self.o it should be a weak proxy in second argument cb.call_args[0][1] # TODO: giles cant work out how to check weakproxy equivalence?? # self.assertEquals(param1, self.o) cb.reset_mock() self.o._q.put(Update(1, "value2")) self.o._q.put(Return(1)) self.o.wait_all_futures(f, 0.01) cb.assert_called_once_with("value2", ANY, "arg2") assert f.result(0.01) is None
def test_unsubscribe(self): # Test that we remove the relevant subscription only and that # updates are no longer sent block = MagicMock(to_dict=MagicMock(return_value={ "attr": "0", "inner": { "attr2": "other" } })) p = Process("proc", MagicMock()) sub_1 = Subscribe(MagicMock(), MagicMock(), ["block"], False) sub_1.response_queue.qsize.return_value = 0 sub_2 = Subscribe(MagicMock(), MagicMock(), ["block"], False) sub_2.response_queue.qsize.return_value = 0 sub_1.set_id(1234) sub_2.set_id(1234) change_1 = BlockChanges([[["block", "attr"], "1"]]) change_2 = BlockChanges([[["block", "attr"], "2"]]) unsub_1 = Unsubscribe(sub_1.context, sub_1.response_queue) unsub_1.set_id(sub_1.id) p.q.get = MagicMock(side_effect=[ sub_1, sub_2, change_1, unsub_1, change_2, PROCESS_STOP ]) p._handle_block_add(BlockAdd(block, "block", None)) p.recv_loop() self.assertEqual([sub_2], list(p._subscriptions.values())) sub_1_responses = sub_1.response_queue.put.call_args_list sub_2_responses = sub_2.response_queue.put.call_args_list self.assertEquals(3, len(sub_1_responses)) self.assertEquals(sub_1_responses[0][0][0].value["attr"], "0") self.assertEquals(sub_1_responses[1][0][0].value["attr"], "1") self.assertIsInstance(sub_1_responses[2][0][0], Return) self.assertEquals(3, len(sub_2_responses)) self.assertEquals(sub_2_responses[0][0][0].value["attr"], "0") self.assertEquals(sub_2_responses[1][0][0].value["attr"], "1") self.assertEquals(sub_2_responses[2][0][0].value["attr"], "2")
def test_unsubscribe(self): # Test that we remove the relevant subscription only and that # updates are no longer sent block = MagicMock( to_dict=MagicMock( return_value={"attr": "0", "inner": {"attr2": "other"}})) p = Process("proc", MagicMock()) sub_1 = Subscribe( MagicMock(), MagicMock(), ["block"], False) sub_1.response_queue.qsize.return_value = 0 sub_2 = Subscribe( MagicMock(), MagicMock(), ["block"], False) sub_2.response_queue.qsize.return_value = 0 sub_1.set_id(1234) sub_2.set_id(1234) change_1 = BlockChanges([[["block", "attr"], "1"]]) change_2 = BlockChanges([[["block", "attr"], "2"]]) unsub_1 = Unsubscribe(sub_1.context, sub_1.response_queue) unsub_1.set_id(sub_1.id) p.q.get = MagicMock(side_effect=[sub_1, sub_2, change_1, unsub_1, change_2, PROCESS_STOP]) p._handle_block_add(BlockAdd(block, "block", None)) p.recv_loop() self.assertEqual([sub_2], list(p._subscriptions.values())) sub_1_responses = sub_1.response_queue.put.call_args_list sub_2_responses = sub_2.response_queue.put.call_args_list self.assertEquals(3, len(sub_1_responses)) self.assertEquals(sub_1_responses[0][0][0].value["attr"], "0") self.assertEquals(sub_1_responses[1][0][0].value["attr"], "1") self.assertIsInstance(sub_1_responses[2][0][0], Return) self.assertEquals(3, len(sub_2_responses)) self.assertEquals(sub_2_responses[0][0][0].value["attr"], "0") self.assertEquals(sub_2_responses[1][0][0].value["attr"], "1") self.assertEquals(sub_2_responses[2][0][0].value["attr"], "2")
def subscribe_server_blocks(self, _): """Subscribe to process blocks""" request = Subscribe(None, None, [".", "blocks", "value"]) request.set_id(self.SERVER_BLOCKS_ID) self.loop.add_callback(self.send_to_server, request)
def test_when_matches(self): self.o._q.put(Update(1, "value1")) self.o._q.put(Return(1)) self.o.when_matches(["block", "attr", "value"], "value1", timeout=0.01) self.assert_handle_request_called_with( Subscribe(1, ["block", "attr", "value"]), Unsubscribe(1))
def setUp(self): self.callback = MagicMock() self.path = ["BL18I:XSPRESS3"] self.delta = True self.o = Subscribe(11, self.path, self.delta) self.o.set_callback(self.callback)
def test_handle_request(self): q = Queue() request = Get(id=41, path=["mri", "myAttribute"], callback=q.put) self.o.handle_request(request) response = q.get(timeout=.1) self.assertIsInstance(response, Return) assert response.id == 41 assert response.value["value"] == "hello_block" # It's part2 that will get the attribute as it was defined second self.part2.myAttribute.meta.writeable = False request = Put(id=42, path=["mri", "myAttribute"], value='hello_block', callback=q.put) self.o.handle_request(request) response = q.get(timeout=.1) self.assertIsInstance(response, Error) # not writeable assert response.id == 42 self.part2.myAttribute.meta.writeable = True self.o.handle_request(request) response = q.get(timeout=.1) self.assertIsInstance(response, Return) assert response.id == 42 assert response.value == "hello_block" request = Post(id=43, path=["mri", "my_method"], callback=q.put) self.o.handle_request(request) response = q.get(timeout=.1) self.assertIsInstance(response, Return) assert response.id == 43 assert response.value['ret'] == "world" # cover the controller._handle_post path for parameters request = Post(id=43, path=["mri", "my_method"], parameters={'dummy': 1}, callback=q.put) self.o.handle_request(request) response = q.get(timeout=.1) self.assertIsInstance(response, Return) assert response.id == 43 assert response.value['ret'] == "world" request = Subscribe(id=44, path=["mri", "myAttribute"], delta=False, callback=q.put) self.o.handle_request(request) response = q.get(timeout=.1) self.assertIsInstance(response, Update) assert response.id == 44 assert response.value["typeid"] == "epics:nt/NTScalar:1.0" assert response.value["value"] == "hello_block" request = Unsubscribe(id=44, callback=q.put) self.o.handle_request(request) response = q.get(timeout=.1) self.assertIsInstance(response, Return) assert response.id == 44