def test_sensor_add_remove(self): """Test a sensor being added and then remove it.""" yield self.client.until_synced() sensor = DeviceTestSensor(Sensor.INTEGER, "another.int", "An Integer.", "count", [-5, 5], timestamp=time.time(), status=Sensor.NOMINAL, value=3) # Check that the sensor does not exist currently self.assertNotIn(sensor.name, self.client.sensors) # Add a sensor. self.server.add_sensor(sensor) self.server.mass_inform(Message.inform('interface-changed')) # Do a blocking request to ensure #interface-changed has been received yield self.client.simple_request('watchdog') yield self.client.until_synced() self.assertIn('another.int', self.client.sensors) # Remove a sensor. self.server.remove_sensor(sensor) self.server.mass_inform(Message.inform('interface-changed')) # Do a blocking request to ensure #interface-changed has been received yield self.client.simple_request('watchdog') yield self.client.until_synced() self.assertNotIn('another.int', self.client.sensors)
def test_request_add_remove(self): """Test a request being added and then remove it.""" yield self.client.until_synced() def request_sparkling_new(self, req, msg): """A new command.""" return Message.reply(msg.name, "ok", "bling1", "bling2") # Check that the request did not exist before self.assertNotIn('sparkling-new', self.client.requests) # Add a request. self.server.request_sparkling_new = request_sparkling_new self.server._request_handlers['sparkling-new'] = request_sparkling_new self.server.mass_inform(Message.inform('interface-changed')) # Do a blocking request to ensure #interface-changed has been received yield self.client.simple_request('watchdog') yield self.client.until_synced() self.assertIn('sparkling-new', self.client.requests) req = yield self.client.future_get_request('sparkling-new') self.assertEqual(req.name, 'sparkling-new') # Remove a request. self.server.request_sparkling_new = None del(self.server._request_handlers['sparkling-new']) self.server.mass_inform(Message.inform('interface-changed')) # Do a blocking request to ensure #interface-changed has been received self.client.simple_request('watchdog') yield self.client.until_synced() self.assertNotIn('sparkling_new', self.client.requests)
def request_foo(self, msg): """ This is called when ?foo is called from the other side. """ # send one inform self.send_message(Message.inform('foo', 'fine')) # return reply return Message.reply('foo', 'ok', '1')
def callback((informs, reply)): self.assertEquals(informs[2:], [Message.inform('sensor-value', '1000', '1', 'device.sensor1', 'unknown', '0'), Message.inform('sensor-value', '0', '1', 'device.sensor2', 'unknown', '0')]) self.assertEquals(reply, Message.reply('sensor-value', 'ok', '4'))
def request_client_list(self, msg): """Request the list of connected clients. The list of clients is sent as a sequence of #client-list informs. Informs ------- addr : str The address of the client as host:port with host in dotted quad notation. If the address of the client could not be determined (because, for example, the client disconnected suddenly) then a unique string representing the client is sent instead. Returns ------- success : {'ok', 'fail'} Whether sending the client list succeeded. informs : int Number of #client-list inform messages sent. Examples -------- :: ?client-list #client-list 127.0.0.1:53600 !client-list ok 1 """ for ip, port in self.factory.clients: self.send_message(Message.inform(msg.name, "%s:%s" % (ip, port))) return Message.reply(msg.name, "ok", len(self.factory.clients))
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_message(Message.inform('help', name, doc)) 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_'):] doc = item.__doc__ if doc is not None: doc = doc.strip() self.send_message(Message.inform('help', sname, doc)) count += 1 return Message.reply(msg.name, "ok", str(count))
def test_request_six(self): """Test client request with no sock and decorators in reverse order.""" self.assertEqual(str(self.device.request_six(Message.request("six", "2", "on", "0"))), "!six ok 2 on 0") self.assertRaises(FailReply, self.device.request_six, Message.request("six", "4", "on", "0")) self.assertRaises(FailReply, self.device.request_six, Message.request("six", "2", "dsfg", "0")) self.assertRaises(FailReply, self.device.request_six, Message.request("six", "2", "on", "3")) self.assertRaises(FailReply, self.device.request_six, Message.request("six", "2", "on"))
def callback((informs, reply)): self.assertEquals(informs[2:], [ Message.inform('sensor-value', '1000', '1', 'device.sensor1', 'unknown', '0'), Message.inform('sensor-value', '0', '1', 'device.sensor2', 'unknown', '0') ]) self.assertEquals(reply, Message.reply('sensor-value', 'ok', '4'))
def test_request_three(self): """Test request with no defaults and decorators in reverse order.""" sock = "" self.assertEqual(str(self.device.request_three(sock, Message.request("three", "2", "on", "0"))), "!three ok 2 on 0") self.assertRaises(FailReply, self.device.request_three, sock, Message.request("three", "4", "on", "0")) self.assertRaises(FailReply, self.device.request_three, sock, Message.request("three", "2", "dsfg", "0")) self.assertRaises(FailReply, self.device.request_three, sock, Message.request("three", "2", "on", "3")) self.assertRaises(FailReply, self.device.request_three, sock, Message.request("three", "2", "on"))
def test_request_int_multifloat(self): req = self.device.request_int_multifloat desired_i, desired_floats = (7, (1.2, 999, 71.43)) self.assertEqual(str(req('req', Message.request( 'int-multifloat', desired_i, *desired_floats))), '!int-multifloat ok 7 1.2 999 71.43') with self.assertRaises(FailReply) as ex: req('req', Message.request('int-multifloat', desired_i, 1.2, 'abc')) self.assertEqual( ex.exception.message, "Error in parameter 3 (): Could not parse value 'abc' as float.")
def test_request_six(self): """Test client request with no req and decorators in reverse order.""" self.assertEqual(str(self.device.request_six(Message.request( "six", "2", "on", "0"))), "!six ok 2 on 0") self.assertRaises(FailReply, self.device.request_six, Message.request("six", "4", "on", "0")) self.assertRaises(FailReply, self.device.request_six, Message.request("six", "2", "dsfg", "0")) self.assertRaises(FailReply, self.device.request_six, Message.request("six", "2", "on", "3")) self.assertRaises(FailReply, self.device.request_six, Message.request("six", "2", "on"))
def request_version_list(self, msg): """Request the list of versions of roles and subcomponents. Informs ------- name : str Name of the role or component. version : str A string identifying the version of the component. Individual components may define the structure of this argument as they choose. In the absence of other information clients should treat it as an opaque string. build_state_or_serial_number : str A unique identifier for a particular instance of a component. This should change whenever the component is replaced or updated. Returns ------- success : {'ok', 'fail'} Whether sending the version list succeeded. informs : int Number of #version-list inform messages sent. Examples -------- :: ?version-list #version-list katcp-protocol 5.0-MI #version-list katcp-library katcp-python-tx-0.4 katcp-python-0.4.1 #version-list katcp-device foodevice-1.0 foodevice-1.0.0rc1 !version-list ok 3 """ versions = [ ("katcp-protocol", (self.PROTOCOL_INFO, None)), ("katcp-library", ("katcp-python-tx-%d.%d" % VERSION[:2], VERSION_STR)), ("katcp-device", (self.version(), self.build_state())), ] extra_versions = sorted(self.extra_versions.items()) for name, (version, build_state) in versions + extra_versions: if build_state is None: inform = Message.inform(msg.name, name, version) else: inform = Message.inform(msg.name, name, version, build_state) self.send_reply_inform(inform, msg) num_versions = len(versions) + len(extra_versions) return Message.reply(msg.name, "ok", str(num_versions))
def test_request_three(self): """Test request with no defaults and decorators in reverse order.""" req = "" self.assertEqual(str(self.device.request_three(req, Message.request( "three", "2", "on", "0"))), "!three ok 2 on 0") self.assertRaises(FailReply, self.device.request_three, req, Message.request("three", "4", "on", "0")) self.assertRaises(FailReply, self.device.request_three, req, Message.request("three", "2", "dsfg", "0")) self.assertRaises(FailReply, self.device.request_three, req, Message.request("three", "2", "on", "3")) self.assertRaises(FailReply, self.device.request_three, req, Message.request("three", "2", "on"))
def fringe_stop(self, enable): # Stop fringe stopping message = Message.request(SWARM_FSTOP_STOP_CMD) reply, informs = self.roach2.blocking_request(message, timeout=60) if not reply.reply_ok(): self.logger.error("Stopping fringe stopping failed!") # Start it again (if requested) if enable: message = Message.request(SWARM_FSTOP_START_CMD) reply, informs = self.roach2.blocking_request(message, timeout=60) if not reply.reply_ok(): self.logger.error("Starting fringe stopping failed!")
def request_drop_connection(self, msg): """ drops connection to specified device, for demo purposes only """ if not msg.arguments: return Message.reply('drop-connection', 'fail', 'Argument required') try: dev_name = msg.arguments[0] self.factory.devices[dev_name].transport.loseConnection() print dev_name, "disconnected" return Message.reply('drop-connection', 'ok') except KeyError: return Message.reply('drop-connection', 'fail', 'Unknown device %s' % dev_name)
def request_device_list(self, reqmsg): """Return a list of devices aggregated by the proxy. Returns the list of devices a sequence of #device-list informs. Inform Arguments ---------------- device : str Name of a device. Returns ------- success : {'ok', 'fail'} Whether sending the list of devices succeeded. informs : int Number of #device-list informs sent. Examples -------- ?device-list #device-list antenna #device-list enviro !device-list ok 2 """ for name in sorted(self.factory.devices): self.send_message( Message.inform("device-list", name, self.factory.devices[name].TYPE)) return "ok", len(self.factory.devices)
def request_device_list(self, reqmsg): """Return a list of devices aggregated by the proxy. Returns the list of devices a sequence of #device-list informs. Inform Arguments ---------------- device : str Name of a device. Returns ------- success : {'ok', 'fail'} Whether sending the list of devices succeeded. informs : int Number of #device-list informs sent. Examples -------- ?device-list #device-list antenna #device-list enviro !device-list ok 2 """ for name in sorted(self.factory.devices): self.send_reply_inform(Message.inform("device-list", name, self.factory.devices[name].TYPE), reqmsg) return "ok", len(self.factory.devices)
def set_delay(self, input_n, value): # Set the delay value in ns message = Message.request(SWARM_DELAY_SET_CMD, str(input_n), str(value)) reply, informs = self.roach2.blocking_request(message, timeout=60) if not reply.reply_ok(): self.logger.error("Setting the delay failed!")
def callback(msg): if device.state is device.UNSYNCED: return Message.reply(dev_name + "-" + req_name, "fail", "Device not synced") d = device.send_request(req_name, *msg.arguments) d.addCallbacks(request_returned, request_failed) raise AsyncReply()
def request_deconfigure(self, req): """ @brief Deconfigure the apsuse worker @param req A katcp request object @return katcp reply object [[[ !deconfigure ok | (fail [error description]) ]]] """ log.info("Received deconfigure request") self._state_sensor.set_value(self.STOPPING) futures = [] for capture_instance in self._capture_instances: capture_instance.target_stop() for sensor in capture_instance._sensors: try: self.remove_sensor(sensor) except Exception as error: log.exception( "Failed to remove sensor with error: {}".format( str(error))) log.warning("Current sensor list: {}".format(self._sensors)) futures.append(capture_instance.capture_stop()) self.mass_inform(Message.inform('interface-changed')) for future in futures: try: yield future except Exception as error: log.exception("Error during capture_stop") raise Return(("fail", str(error))) self._state_sensor.set_value(self.IDLE) log.info("Deconfigured worker server") raise Return(("ok",))
def test_request_eight(self): """Test server request with a message argument.""" sock = "" self.assertEqual( str(self.device.request_eight(sock, Message.request("eight", "8"))), "!eight ok 8 eight")
def worked((informs, reply)): self.flushLoggedErrors() # clean up error about conn lost self.proxy.on_device_ready = Deferred().addCallback(back) self.assertEquals(informs, [ Message.inform("sensor-value", "device.rogue", "Sensor reading failed.") ])
def request_target_configuration_start(self, req, product_id, target_string): """ @brief Set up a beam configuration sensor for the FBFUSE instance @param product_id The product identifier @param target_string A KATPOINT target string (boresight pointing position) """ log.info( "Received target configuration request for '{}' with target: {}". format(product_id, target_string)) if not product_id in self._configuration_sensors: log.debug( "Creating configuration sensor for '{}'".format(product_id)) self._configuration_sensors[product_id] = Sensor.string( "{}-beam-position-configuration".format(product_id), description="Configuration description for FBF beam placement", default="", initial_status=Sensor.UNKNOWN) self.add_sensor(self._configuration_sensors[product_id]) self.mass_inform(Message.inform('interface-changed')) initial_config = yield self.get_target_config(product_id, target_string) self.update_target_config(product_id, initial_config) raise Return(("ok", ))
def setup_sensors(self): """ @brief Setup the default KATCP sensors. @note As this call is made only upon an PAF configure call a mass inform is required to let connected clients know that the proxy interface has changed. """ self._state_sensor = LoggingSensor.discrete( "state", description="Denotes the state of this PAF instance", params=self.STATES, default=self.IDLE, initial_status=Sensor.NOMINAL) self._state_sensor.set_logger(self.log) self.add_sensor(self._state_sensor) self._servers_sensor = Sensor.string( "servers", description= "The worker server instances currently allocated to this product", default=",".join([ "{s.hostname}:{s.port}".format(s=server) for server in self._servers ]), initial_status=Sensor.UNKNOWN) self.add_sensor(self._servers_sensor) self._parent.mass_inform(Message.inform('interface-changed')) self._state_sensor.set_value(self.IDLE)
def send_request(self, name, *args): if not self.transport.connected: raise DeviceNotConnected() d = Deferred() self.send_message(Message.request(name, *args)) self.queries.append((name, d, [])) return d
def get_sensor_dict(self): ''' Create or update sensor dictionary ''' if self.fpga.is_connected(): # Multiplicative factor to apply to each. This assumes specific # ROACH2 sensor sampling--this could change if ROACH # tcpborphserver3 is updated factor = [0] + [0.001] * 3 + [1] * 4 + [0.001] * 18 keys = [] values = [] reply, sensors = self.fpga.blocking_request( Message.request('sensor-list')) if reply.arguments[0] == 'ok': # Got sensor list okay n = int(reply.arguments[1]) reply, vals = self.fpga.blocking_request( Message.request('sensor-value')) self.sensor_dict = {} if reply.arguments[0] == 'ok': # Got sensor values okay if n == int(reply.arguments[1]): # The numbers of sensors and values agree! # Skip first "sensor" which is the mode for i in range(1, n): name = sensors[i].arguments[0][4:] keys.append(name) values.append( int(vals[i].arguments[-1]) * factor[i]) keys.append(name + '.status') values.append(vals[i].arguments[-2]) else: self.sensors = {} self.msg = 'Could not init sensors--names,values are different lengths' return else: self.sensors = {} self.msg = 'Could not init sensors:', reply.arguments[0] return else: self.sensors = {} self.msg = 'Could not init sensors:', reply.arguments[0] return self.sensors = dict(zip(keys, values)) self.msg = 'Success' else: self.msg = 'Could not update sensors--client not connected'
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 request_add_sensor(self, msg): self.factory.add_sensor( Sensor(int, 'int_sensor%d' % len(self.factory.sensors), 'descr', 'unit', params=[-10, 10])) return Message.reply('add-sensor', 'ok')
def test_request_two(self): """Test request with defaults.""" sock = "" self.assertEqual( str( self.device.request_two(sock, Message.request("two", "2", "on", "0"))), "!two ok 2 on 0") self.assertRaises(FailReply, self.device.request_two, sock, Message.request("two", "4", "on", "0")) self.assertRaises(FailReply, self.device.request_two, sock, Message.request("two", "2", "dsfg", "0")) self.assertRaises(FailReply, self.device.request_two, sock, Message.request("two", "2", "on", "3")) self.assertEqual( str( self.device.request_two(sock, Message.request("two", "2", "on"))), "!two ok 2 on 1") self.assertEqual( str(self.device.request_two(sock, Message.request("two", "2"))), "!two ok 2 off 1") self.assertEqual( str(self.device.request_two(sock, Message.request("two"))), "!two ok 2 off 1")
def test_katcpv4_multi(self): tss = (1234, 5678, 9012) # In milliseconds req = mock.Mock() ret_msg = self.device.request_katcpv4_time_multi(req, Message.request( 'katcpv4-time-multi', *(str(ts) for ts in tss) )) for i, ts in enumerate(tss): self.assertAlmostEqual(float(ret_msg.arguments[i+1]), ts) self.assertAlmostEqual(self.device.katcpv4_time_multi[i], ts*MS_TO_SEC_FAC)
def add_pipeline_sensors(self): """ @brief Add pipeline sensors to the managed sensors list """ for sensor in self._pipeline_instance.sensors: self.add_sensor(sensor) self._managed_sensors.append(sensor) self.mass_inform(Message.inform('interface-changed'))
def remove_pipeline_sensors(self): """ @brief Remove pipeline sensors from the managed sensors list """ for sensor in self._managed_sensors: self.remove_sensor(sensor) self._managed_sensors = [] self.mass_inform(Message.inform('interface-changed'))
def historical_sensor_list(self, sensor_filter=''): reply, informs = self.blocking_request( Message.request('historical-sensor-list', sensor_filter)) if reply.arguments[0] == 'ok': result = [inform.arguments for inform in informs] else: logger.warn(reply) result = [] return result
def get_delay(self, input_n): # Get the delay value in ns message = Message.request(SWARM_DELAY_GET_CMD, str(input_n)) reply, informs = self.roach2.blocking_request(message, timeout=60) if not reply.reply_ok(): self.logger.error("Getting the delay failed!") else: return float(reply.arguments[1])
def test_interface_change(self): DUT = yield self._get_DUT_and_sync(self.default_resource_spec) sensors_before = set(DUT.sensor) reqs_before = set(DUT.req) # Add a new sensor to the server sensor = DeviceTestSensor(DeviceTestSensor.INTEGER, "another.int", "An Integer.", "count", [-5, 5], timestamp=self.io_loop.time(), status=DeviceTestSensor.NOMINAL, value=3) self.server.add_sensor(sensor) # Check that the sensor does not exist currently self.assertNotIn(resource.escape_name(sensor.name), sensors_before) # Add a new request to the server def request_sparkling_new(self, req, msg): """A new command.""" return Message.reply(msg.name, "ok", "bling1", "bling2") self.server._request_handlers['sparkling-new'] = request_sparkling_new # Check that the request did not exist before self.assertNotIn('sparkling-new', reqs_before) # Issue #interface-changed self.server.mass_inform(Message.inform('interface-changed')) yield DUT.until_state('syncing') yield DUT.until_state('synced') # Check if sensor/request was added self.assertEqual(set(DUT.sensor) - sensors_before, set(['another_int'])) self.assertEqual(set(DUT.req) - reqs_before, set(['sparkling_new'])) # And now remove them again self.server._request_handlers.pop('sparkling-new') self.server.remove_sensor('another.int') # Issue #interface-changed self.server.mass_inform(Message.inform('interface-changed')) yield DUT.until_state('syncing') yield DUT.until_state('synced') # Check if sensor/request was removed self.assertEqual(set(DUT.sensor), sensors_before) self.assertEqual(set(DUT.req), reqs_before)
def test_request_one(self): """Test request with no defaults.""" sock = "" self.assertEqual(str(self.device.request_one(sock, Message.request("one", "2", "on", "0"))), "!one ok 2 on 0") self.assertRaises(FailReply, self.device.request_one, sock, Message.request("one", "14", "on", "0")) self.assertRaises(FailReply, self.device.request_one, sock, Message.request("one", "2", "dsfg", "0")) self.assertRaises(FailReply, self.device.request_one, sock, Message.request("one", "2", "on", "3")) self.assertRaises(FailReply, self.device.request_one, sock, Message.request("one", "2", "on", "0", "3")) self.assertRaises(FailReply, self.device.request_one, sock, Message.request("one", "2", "on")) self.assertEqual(str(self.device.request_one(sock, Message.request("one", "3", "on", "0"))), "!one fail I\\_failed!") self.assertRaises(ValueError, self.device.request_one, sock, Message.request("one", "5", "on", "0")) self.assertRaises(ValueError, self.device.request_one, sock, Message.request("one", "6", "on", "0")) self.assertRaises(AsyncReply, self.device.request_one, "mysock", Message.request("one", "9", "on", "0")) self.assertEqual(len(self.device.sent_messages), 1) self.assertEqual(self.device.sent_messages[0][0], "mysock") self.assertEqual(str(self.device.sent_messages[0][1]), "!one ok 9 on 0")
def teardown_sensors(self): """ @brief Remove all sensors created by this product from the parent server. @note This method is required for cleanup to stop the APS sensor pool becoming swamped with unused sensors. """ for sensor in self._managed_sensors: self._parent.remove_sensor(sensor) self._managed_sensors = [] self._parent.mass_inform(Message.inform('interface-changed'))
def test_request_int_multifloat(self): req = self.device.request_int_multifloat desired_i, desired_floats = (7, (1.2, 999, 71.43)) self.assertEqual( str( req( 'req', Message.request('int-multifloat', desired_i, *desired_floats))), '!int-multifloat ok 7 1.2 999.0 71.43') with self.assertRaises(FailReply) as ex: req('req', Message.request('int-multifloat', desired_i, 1.2, 'abc')) # storing Message.arguments as byte string results in slightly different # reprs for PY2 compared to PY3. if future.utils.PY2: expected = "Error in parameter 3 (): Could not parse value 'abc' as float." else: expected = "Error in parameter 3 (): Could not parse value 'b'abc'' as float." self.assertEqual(str(ex.exception), expected)
def test_katcpv4(self): ts = 12345678 # In milliseconds req = mock.Mock() ret_msg = self.device.request_katcpv4_time(req, Message.request( 'katcpv4-time', str(ts))) self.assertTrue(ret_msg.reply_ok()) self.assertAlmostEqual(float(ret_msg.arguments[1]), ts) # Test decorator default value self.assertAlmostEqual(float(ret_msg.arguments[2]), 321*SEC_TO_MS_FAC) self.assertAlmostEqual(self.device.katcpv4_time1*SEC_TO_MS_FAC, ts) self.assertEqual(self.device.katcpv4_time2, None) ts1 = 1234 ts2 = 2345 ret_msg = self.device.request_katcpv4_time(req, Message.request( 'katcpv4-time', str(ts1), str(ts2))) self.assertTrue(ret_msg.reply_ok()) self.assertAlmostEqual(float(ret_msg.arguments[1]), ts1) self.assertAlmostEqual(float(ret_msg.arguments[2]), ts2) self.assertAlmostEqual(self.device.katcpv4_time1*SEC_TO_MS_FAC, ts1) self.assertAlmostEqual(self.device.katcpv4_time2*SEC_TO_MS_FAC, ts2)
def __getattr__(self, attr): # TODO: It would be cleaner if a new request method / callback # wasn't created for every proxied request. # TODO: These proxied methods should appear in the ?help for the proxy # but currently don't. def request_returned((informs, reply), reqmsg): assert informs == [] # for now # we *could* in theory just change message name, but let's copy # just in case self.send_reply(Message.reply(dev_name + "-" + req_name, *reply.arguments), reqmsg)
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 handle_request(self, msg): name = msg.name name = name.replace('-', '_') try: rep_msg = getattr(self, 'request_' + name, self._request_unknown)(msg) if not isinstance(rep_msg, Message): raise ShouldReturnMessage('request_' + name + ' should return a' 'message or raise AsyncReply, instead' 'it returned %r' % rep_msg) self.send_message(rep_msg) except FailReply, fr: self.send_message(Message.reply(name, "fail", str(fr)))
def test_request_two(self): """Test request with defaults.""" sock = "" self.assertEqual(str(self.device.request_two(sock, Message.request("two", "2", "on", "0"))), "!two ok 2 on 0") self.assertRaises(FailReply, self.device.request_two, sock, Message.request("two", "4", "on", "0")) self.assertRaises(FailReply, self.device.request_two, sock, Message.request("two", "2", "dsfg", "0")) self.assertRaises(FailReply, self.device.request_two, sock, Message.request("two", "2", "on", "3")) self.assertEqual(str(self.device.request_two(sock, Message.request("two", "2", "on"))), "!two ok 2 on 1") self.assertEqual(str(self.device.request_two(sock, Message.request("two", "2"))), "!two ok 2 off 1") self.assertEqual(str(self.device.request_two(sock, Message.request("two"))), "!two ok 2 off 1")
def request_one(self, sock, i, d, b): if i == 3: return ("fail", "I failed!") if i == 5: return ("bananas", "This should never be sent") if i == 6: return ("ok", i, d, b, "extra parameter") if i == 9: # This actually gets put in the callback params automatically orig_msg = Message.request("one", "foo", "bar") self.finish_request_one(orig_msg, sock, i, d, b) raise AsyncReply() return ("ok", i, d, b)
def _request(self, name, *args, **kwargs): request = Message.request(name, *args) try: reply, informs = self.blocking_request(request, keepalive=True) except TypeError: retry = kwargs.pop('retry', 0) self.logger.error("Error using blocking_request, try number %d" % retry) return self._request(name, *args, retry=retry+1) if reply.arguments[0] != Message.OK: self._logger.error("Request %s failed.\n Request: %s\n Reply: %s." % (request.name, request, reply)) raise RuntimeError("Request %s failed.\n Request: %s\n Reply: %s." % (request.name, request, reply)) return reply, informs
def send_katcp_cmd(self, cmd, *args): # Create the message object message = Message.request(cmd, *args) # Send the request, and block for 60 seconds reply, informs = self.roach2.blocking_request(message, timeout=60) # Check for error, and raise one if present if not reply.reply_ok(): raise RuntimeError(reply) # Otherwise return what we got return reply, informs
def test_request_five(self): """Test client request with no sock.""" self.assertEqual(str(self.device.request_five(Message.request("five", "2", "on", "0"))), "!five ok 2 on 0") self.assertRaises(FailReply, self.device.request_five, Message.request("five", "14", "on", "0")) self.assertRaises(FailReply, self.device.request_five, Message.request("five", "2", "dsfg", "0")) self.assertRaises(FailReply, self.device.request_five, Message.request("five", "2", "on", "3")) self.assertRaises(FailReply, self.device.request_five, Message.request("five", "2", "on", "0", "3")) self.assertRaises(FailReply, self.device.request_five, Message.request("five", "2", "on"))
def _log_msg(self, level_name, msg, name, timestamp=None): """Create a katcp logging inform message. Usually this will be called from inside a DeviceLogger object, but it is also used by the methods in this class when errors need to be reported to the client. """ if timestamp is None: timestamp = time.time() return Message.inform("log", level_name, str(int(timestamp * 1000.0)), # time since epoch in ms name, msg, )