def test_if_buffer_has_wrong_id_then_throws(self): original_entry = {"config_change": UpdateType.REMOVEALL, "streams": []} buf = serialise_rf5k(**original_entry) # Manually hack the id buf = bytearray(buf) buf[4:8] = b"1234" with pytest.raises(RuntimeError): deserialise_rf5k(buf)
def parse_config_update(config_update_payload: bytes) -> ConfigUpdate: try: config_update = deserialise_rf5k(config_update_payload) except (RuntimeError, flatbuffer_struct.error): logger.warning( "Unable to deserialise payload of received configuration update message" ) return ConfigUpdate(CommandType.MALFORMED, None) try: command_type = config_change_to_command_type[config_update.config_change] except KeyError: logger.warning( "Unrecogised configuration change type in configuration update message" ) return ConfigUpdate(CommandType.MALFORMED, None) if command_type == CommandType.REMOVE_ALL: return ConfigUpdate(CommandType.REMOVE_ALL, None) parsed_streams = tuple(_parse_streams(command_type, config_update.streams)) if ( command_type == CommandType.ADD or command_type == CommandType.REMOVE ) and not parsed_streams: logger.warning( "Configuration update message requests adding or removing streams " "but does not contain valid details of streams" ) return ConfigUpdate(CommandType.MALFORMED, None) return ConfigUpdate(command_type, parsed_streams)
def test_parse_streams_skips_stream_info_if_remove_config_and_channel_name_schema_and_topic_not_specified( ): message = serialise_rf5k( UpdateType.REMOVE, [StreamInfo("", "", "", Protocol.PVA)], ) config_message = deserialise_rf5k(message) streams = tuple(_parse_streams(CommandType.REMOVE, config_message.streams)) assert not streams
def test_parse_streams_parses_valid_add_config(): test_channel_name = "test_channel" message = serialise_rf5k( UpdateType.ADD, [StreamInfo(test_channel_name, "f142", "output_topic", Protocol.PVA)], ) config_message = deserialise_rf5k(message) streams = tuple(_parse_streams(CommandType.ADD, config_message.streams)) assert len(streams) == 1 assert streams[0].name == test_channel_name
def test_parse_streams_skips_stream_info_if_add_config_and_topic_not_specified( ): empty_topic = "" message = serialise_rf5k( UpdateType.ADD, [StreamInfo("test_channel", "f142", empty_topic, Protocol.PVA)], ) config_message = deserialise_rf5k(message) streams = tuple(_parse_streams(CommandType.ADD, config_message.streams)) assert not streams
def test_remove_config_is_valid_if_channel_name_not_specified_but_topic_is(): test_topic = "output_topic" message = serialise_rf5k( UpdateType.REMOVE, [StreamInfo("", "", test_topic, Protocol.PVA)], ) config_message = deserialise_rf5k(message) streams = tuple(_parse_streams(CommandType.REMOVE, config_message.streams)) assert len(streams) == 1 assert streams[0].output_topic == test_topic
def test_remove_config_is_valid_with_all_channel_info_specified(): test_channel_name = "test_channel" message = serialise_rf5k( UpdateType.REMOVE, [StreamInfo(test_channel_name, "f142", "output_topic", Protocol.PVA)], ) config_message = deserialise_rf5k(message) streams = tuple(_parse_streams(CommandType.REMOVE, config_message.streams)) assert len(streams) == 1 assert streams[0].name == test_channel_name
def test_parse_streams_skips_stream_info_if_add_config_and_schema_not_recognised( ): nonexistent_schema = "NONEXISTENT" message = serialise_rf5k( UpdateType.ADD, [ StreamInfo("test_channel", nonexistent_schema, "output_topic", Protocol.PVA) ], ) config_message = deserialise_rf5k(message) streams = tuple(_parse_streams(CommandType.ADD, config_message.streams)) assert not streams
def test_serialises_and_deserialises_rf5k_message_without_streams_correctly( self): """ Round-trip to check what we serialise is what we get back. """ original_entry = { "config_change": UpdateType.REMOVEALL, "streams": [], } buf = serialise_rf5k(**original_entry) entry = deserialise_rf5k(buf) assert entry.config_change == original_entry["config_change"]
def test_parse_streams_parses_valid_stream_after_skipping_invalid_stream(): nonexistent_schema = "NONEXISTENT" valid_stream_channel_name = "test_valid_stream" message = serialise_rf5k( UpdateType.ADD, [ StreamInfo("test_invalid_stream", nonexistent_schema, "output_topic", Protocol.PVA), StreamInfo(valid_stream_channel_name, "f142", "output_topic", Protocol.PVA), ], ) config_message = deserialise_rf5k(message) streams = tuple(_parse_streams(CommandType.ADD, config_message.streams)) assert len(streams) == 1 assert streams[0].name == valid_stream_channel_name
def test_add_pvs(self): messages = create_random_messages(10, num_pvs=5) pv_details = create_pv_details_from_messages(messages) with mock.patch.object(EpicsKafkaForwarderControl, "send") as mock_send: self.monitor.add(pv_details) call_topic, call_command = mock_send.call_args[0] assert call_topic == self.control.cmdtopic entry = deserialise_rf5k(call_command) assert entry.config_change == UpdateType.UpdateType.ADD topics = set() for stream in entry.streams: assert stream.schema == "f142" assert stream.topic == "TEST_metadata" topics.add(stream.channel) assert topics == set(pv_details.keys())
def test_add_pvs(self): pvnames = {f'mypv{i}' for i in range(10)} message = {'streams': [create_stream(pv) for pv in pvnames]} pv_details = create_pv_details_from_messages({1236: message}) with mock.patch.object( EpicsKafkaForwarderControl, 'send' ) as mock_send: self.device.add(pv_details) call_topic, call_command = mock_send.call_args[0] assert call_topic == self.device.cmdtopic entry = deserialise_rf5k(call_command) assert entry.config_change == UpdateType.UpdateType.ADD topics = set() for stream in entry.streams: assert stream.schema == 'f142' assert stream.topic == 'TEST_metadata' topics.add(stream.channel) assert topics == set(pv_details.keys())
def test_serialises_and_deserialises_rf5k_message_with_streams_correctly( self): """ Round-trip to check what we serialise is what we get back. """ stream_1 = StreamInfo("channel1", "f142", "topic1", Protocol.Protocol.PVA) stream_2 = StreamInfo("channel2", "TdcTime", "topic2", Protocol.Protocol.CA) original_entry = { "config_change": UpdateType.ADD, "streams": [stream_1, stream_2], } buf = serialise_rf5k(**original_entry) entry = deserialise_rf5k(buf) assert entry.config_change == original_entry["config_change"] assert stream_1 in entry.streams assert stream_2 in entry.streams