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)
Beispiel #2
0
 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()
Beispiel #3
0
    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
Beispiel #4
0
 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)
Beispiel #5
0
    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)
Beispiel #6
0
 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)
Beispiel #7
0
 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)
Beispiel #8
0
    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)
Beispiel #9
0
    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
Beispiel #10
0
 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)
Beispiel #11
0
 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)
Beispiel #12
0
    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))
Beispiel #13
0
 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))
Beispiel #14
0
    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
Beispiel #15
0
    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()
Beispiel #16
0
 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))
     ]
Beispiel #17
0
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
Beispiel #19
0
    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))
Beispiel #20
0
 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))
     ]
Beispiel #21
0
    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))
Beispiel #22
0
 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)
Beispiel #25
0
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()
Beispiel #26
0
    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()
Beispiel #28
0
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)
Beispiel #29
0
    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)
Beispiel #30
0
 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
Beispiel #31
0
    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 __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)
Beispiel #33
0
    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")
Beispiel #34
0
 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)
Beispiel #35
0
 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))
Beispiel #36
0
 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)
Beispiel #37
0
    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
Beispiel #38
0
 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)