Exemple #1
0
 def test_preset(self):
     self.client.preset_protocol_flags(
         ProtocolFlags(5, 0, [ProtocolFlags.MESSAGE_IDS]))
     self._check_v5_mid()
     self.client._received_protocol_info.clear()
     self.client.preset_protocol_flags(ProtocolFlags(4, 0, ''))
     self._check_v4()
Exemple #2
0
    def test_preset_v5_then_v4(self):
        def check_warn_not_disconect():
            self.assertEqual(self.client._disconnect.call_count, 0)
            self.assertEqual(self.client._auto_reconnect, True)
            self.assertEqual(self.client._logger.warn.call_count, 1)
            log_msg = self.client._logger.warn.call_args[0][0]
            self.assertIn('Protocol Version', log_msg)
            self.client._logger.warn.reset_mock()

        self.client.preset_protocol_flags(
            ProtocolFlags(5, 0, [ProtocolFlags.MESSAGE_IDS]))
        self._check_v5_mid()
        self.client._disconnect = mock.Mock()
        self.client._logger = mock.Mock()
        # Any Version 4-identifying informs should cause warnings
        self.client.handle_message(self.v4_build_state)
        check_warn_not_disconect()
        self._check_v5_mid()
        self.client.handle_message(self.v4_version)
        check_warn_not_disconect()
        self._check_v5_mid()
        # A version 5 version-connect message with different flags should also
        # result in a warning
        self.client.handle_message(self.v5_version_connect_nomid)
        check_warn_not_disconect()
        self._check_v5_mid()
        # An identical version 5 version-connect message should not result in
        # any warnings
        self.client.handle_message(self.v5_version_connect_mid)
        self.assertEqual(self.client._disconnect.call_count, 0)
        self.assertEqual(self.client._logger.warn.call_count, 0)
        self.assertEqual(self.client._auto_reconnect, True)
        self._check_v5_mid()
Exemple #3
0
 def test_preset_v4_then_v5(self):
     self.client.preset_protocol_flags(ProtocolFlags(4, 0, ''))
     self._check_v4()
     self.client._disconnect = mock.Mock()
     self.client._logger = mock.Mock()
     # A version 5 version-connect message should result in a warning
     self.client.handle_message(self.v5_version_connect_mid)
     self.assertEqual(self.client._disconnect.call_count, 0)
     self.assertEqual(self.client._auto_reconnect, True)
     self.assertEqual(self.client._logger.warn.call_count, 1)
     log_msg = self.client._logger.warn.call_args[0][0]
     self.assertIn('Protocol Version', log_msg)
     self._check_v4()
     self.client._logger.warn.reset_mock()
     # Version 4-identifying informs should not cause any warnings
     self.client.handle_message(self.v4_version)
     self.client.handle_message(self.v4_build_state)
     self.assertEqual(self.client._disconnect.call_count, 0)
     self.assertEqual(self.client._auto_reconnect, True)
     self.assertEqual(self.client._logger.warn.call_count, 0)
     self._check_v4()
Exemple #4
0
    def katcp_rct(self):
        try:
            katcp_prot = self.test_config['inst_param']['katcp_protocol']
        except TypeError:
            LOGGER.error('Failed to read katcp protocol from test config file')
        else:
            _major, _minor, _flags = katcp_prot.split(',')
            protocol_flags = ProtocolFlags(int(_major), int(_minor), _flags)
        multicast_ip = self.get_multicast_ips
        if not multicast_ip:
            LOGGER.error('Failed to calculate multicast IP\'s')
            self._katcp_rct = None
            return

        if self._katcp_rct is None:
            try:
                reply, informs = self.rct.req.subordinate_list(self.array_name)
            except TypeError:
                msg = 'Failed to list all arrays with name: %s' %self.array_name
                LOGGER.exception(msg)
            # If no sub-array present create one, but this could cause problems
            # if more than one sub-array is present. Update this to check for
            # required sub-array.
            if reply.reply_ok():
                self.katcp_array_port = int(informs[0].arguments[1])
            else:
                LOGGER.info('Array has not been assigned yet, will try to assign.'
                            ' File:%s Line:%s' % (
                                getframeinfo(currentframe()).filename.split('/')[-1],
                                getframeinfo(currentframe()).lineno))
                try:
                    reply, _informs = self.rct.req.subordinate_create(self.array_name,
                                                                *multicast_ip)
                    assert reply.reply_ok()
                except (ValueError, TypeError, AssertionError):
                    try:
                        reply, informs = self.rct.req.subordinate_list()
                        assert reply.reply_ok()
                        informs = informs[0]
                        if len(informs.arguments) >= 10 and self.array_name == informs.arguments[0]:
                            msg = 'Array assigned successfully: %s' %str(informs)
                            LOGGER.info(msg)
                        else:
                            LOGGER.error('Halting array.')
                            reply, informs = self.rct.req.subordinate_halt(self.array_name,
                                timeout=_timeout)
                            assert reply.reply_ok()
                    except AssertionError:
                        LOGGER.exception('Failed to assign multicast ip on array: %s: \n\nReply: %s' % (
                            self.array_name, str(reply)))
                else:
                    if len(reply.arguments) == 2:
                        try:
                            self.katcp_array_port = int(reply.arguments[-1])
                            LOGGER.info('Array %s assigned successfully' % (self.katcp_array_port))
                        except ValueError:
                            # self.rct.req.subordinate_halt(self.array_name)
                            # self.rct.stop()
                            # self.rct.start()
                            # self.rct.until_synced(timeout=_timeout)
                            # reply, informs = self.rct.req.subordinate_create(self.array_name,
                            # *multicast_ip)
                            errmsg = 'Investigate as to why this thing failed.'
                            LOGGER.exception(errmsg)
                            sys.exit(errmsg)

            katcp_rc = resource_client.KATCPClientResource(
                dict(name='{}'.format(self.katcp_clt),
                     address=('{}'.format(self.katcp_clt),
                              '{}'.format(self.katcp_array_port)),
                     preset_protocol_flags=protocol_flags, controlled=True))
            katcp_rc.set_ioloop(self.io_manager.get_ioloop())
            self._katcp_rct = (
                resource_client.ThreadSafeKATCPClientResourceWrapper(
                    katcp_rc, self.io_wrapper))
            self._katcp_rct.start()
            try:
                self._katcp_rct.until_synced(timeout=_timeout)
            except Exception as e:
                self._katcp_rct.stop()
                LOGGER.exception('Failed to connect to katcp due to %s' %str(e))
            LOGGER.info('Cleanup function \'self._katcp_rct\': File: %s line: %s' % (
                getframeinfo(currentframe()).filename.split('/')[-1],
                getframeinfo(currentframe()).lineno))
            # add_cleanup(self._katcp_rct.stop)
        else:
            self._katcp_rct.start()
            try:
                time.sleep(1)
                self._katcp_rct.until_synced(timeout=_timeout)
            except Exception as e:
                self._katcp_rct.stop()
                LOGGER.exception('Failed to connect to katcp due to %s' %str(e))
        return self._katcp_rct
Exemple #5
0
 def _connect(self):
     assert get_thread_ident() == self.ioloop_thread_id
     self._stream = AttrDict(error=None)
     self._connected.set()
     self.notify_connected(True)
     self.preset_protocol_flags(ProtocolFlags(5, 0, set('IM')))
Exemple #6
0
class ServerKatCPProtocol(KatCP):
    VERSION = ("device_stub", 0, 1)
    BUILD_STATE = ("name", 0, 1, "")
    PROTOCOL_INFO = ProtocolFlags(5, 0, set([
        ProtocolFlags.MULTI_CLIENT,
    ]))

    def connectionMade(self):
        """ Called when connection is made. Send default informs - version
        and build data
        """
        self.transport.registerProducer(self, True)

        katcp_version = self.PROTOCOL_INFO.major
        if katcp_version >= VERSION_CONNECT_KATCP_MAJOR:
            self.send_message(
                Message.inform("version-connect", "katcp-protocol",
                               self.PROTOCOL_INFO))
            self.send_message(
                Message.inform("version-connect", "katcp-library",
                               "katcp-python-tx-%s" % VERSION_STR))
            self.send_message(
                Message.inform("version-connect", "katcp-device",
                               self.version(), self.build_state()))
        else:
            self.send_message(Message.inform("version", self.version()))
            self.send_message(Message.inform("build-state",
                                             self.build_state()))

    def build_state(self):
        """Return a build state string in the form
        name-major.minor[(a|b|rc)n]
        """
        return "%s-%s.%s%s" % self.BUILD_STATE

    def version(self):
        """Return a version string of the form type-major.minor."""
        return "%s-%s.%s" % self.VERSION

    def request_help(self, msg):
        """Return help on the available requests.

        Return a description of the available requests using a seqeunce of
        #help informs.

        Parameters
        ----------
        request : str, optional
            The name of the request to return help for (the default is to
            return help for all requests).

        Informs
        -------
        request : str
            The name of a request.
        description : str
            Documentation for the named request.

        Returns
        -------
        success : {'ok', 'fail'}
            Whether sending the help succeeded.
        informs : int
            Number of #help inform messages sent.

        Examples
        --------
        ::

            ?help
            #help halt ...description...
            #help help ...description...
            ...
            !help ok 5

            ?help halt
            #help halt ...description...
            !help ok 1
        """
        if msg.arguments:
            name = msg.arguments[0]
            meth = getattr(self, 'request_' + name.replace('-', '_'), None)
            if meth is None:
                return Message.reply('help', 'fail', 'Unknown request method.')
            doc = meth.__doc__
            if doc is not None:
                doc = doc.strip()
            self.send_reply_inform(Message.inform('help', name, doc), msg)
            return Message.reply('help', 'ok', '1')
        count = 0
        for name in dir(self.__class__):
            item = getattr(self, name)
            if name.startswith('request_') and callable(item):
                sname = name[len('request_'):].replace('_', '-')
                doc = item.__doc__
                if doc is not None:
                    doc = doc.strip()
                self.send_reply_inform(Message.inform('help', sname, doc), msg)
                count += 1
        return Message.reply(msg.name, "ok", str(count))
    def katcp_rct_sensor(self):
        if self._katcp_rct_sensor is None:
            try:
                katcp_prot = self.test_config['instrument_params'][
                    'katcp_protocol']
                _major, _minor, _flags = katcp_prot.split(',')
                protocol_flags = ProtocolFlags(int(_major), int(_minor),
                                               _flags)
                LOGGER.info('katcp protocol flags %s' % protocol_flags)

                LOGGER.info('Getting running array.')
                reply, informs = self.rct.req.subordinate_list(self.array_name)
                assert reply.reply_ok()
                # If no sub-array present create one, but this could cause problems
                # if more than one sub-array is present. Update this to check for
                # required sub-array.
            except Exception:
                LOGGER.exception('Failed to list all arrays with name: %s' %
                                 self.array_name)
            else:
                try:
                    try:
                        self.katcp_array_port = int(informs[0].arguments[1])
                        LOGGER.info(
                            'Current running array name: %s, port: %s' %
                            (self.array_name, self.katcp_array_port))
                    except ValueError:
                        self.katcp_array_port, self.katcp_sensor_port = informs[
                            0].arguments[1].split(',')
                        LOGGER.info(
                            'Current running array name: %s, port: %s, sensor port: %s'
                            % (self.array_name, self.katcp_array_port,
                               self.katcp_sensor_port))
                except Exception:
                    errmsg = (
                        'Failed to retrieve running array, ensure one has been created and running'
                    )
                    LOGGER.exception(errmsg)
                    sys.exit(errmsg)
                else:
                    katcp_rc = resource_client.KATCPClientResource(
                        dict(name='{}'.format(self.katcp_client),
                             address=('{}'.format(self.katcp_client),
                                      '{}'.format(self.katcp_sensor_port)),
                             preset_protocol_flags=protocol_flags,
                             controlled=True))
                    katcp_rc.set_ioloop(self.io_manager.get_ioloop())
                    self._katcp_rct_sensor = (
                        resource_client.ThreadSafeKATCPClientResourceWrapper(
                            katcp_rc, self.io_wrapper))
                    self._katcp_rct_sensor.start()
                    try:
                        self._katcp_rct_sensor.until_synced(timeout=_timeout)
                    except Exception as e:
                        self._katcp_rct_sensor.stop()
                        LOGGER.exception(
                            'Failed to connect to katcp due to %s' % str(e))
                    else:
                        return self._katcp_rct_sensor
        else:
            if not self._katcp_rct_sensor.is_active():
                LOGGER.info(
                    'katcp resource client wasnt running, hence we need to start it.'
                )
                self._katcp_rct_sensor.start()
                try:
                    time.sleep(1)
                    self._katcp_rct_sensor.until_synced(timeout=_timeout)
                    return self._katcp_rct_sensor
                except Exception:
                    self._katcp_rct_sensor.stop()
                    LOGGER.exception('Failed to connect to katcp')
            else:
                return self._katcp_rct_sensor