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()
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()
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()
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
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')))
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