From 180aa559598010a2843c7bcfed634b61317a5fdb Mon Sep 17 00:00:00 2001 From: Jim Hofman Date: Wed, 28 Sep 2022 12:40:51 -0700 Subject: [PATCH 1/8] issue-368 --- ait/core/server/broker.py | 6 +- .../server/handlers/ccsds_packet_handler.py | 22 +++---- ait/core/server/handlers/packet_handler.py | 47 ++++++++++---- ait/core/server/server.py | 6 +- ait/core/tlm.py | 5 +- tests/ait/core/server/test_handler.py | 64 ++++++++++++++++++- 6 files changed, 112 insertions(+), 38 deletions(-) diff --git a/ait/core/server/broker.py b/ait/core/server/broker.py index 72c4e308..407a8c25 100644 --- a/ait/core/server/broker.py +++ b/ait/core/server/broker.py @@ -1,8 +1,8 @@ -import zmq.green as zmq import gevent -import gevent.monkey +from gevent import monkey +monkey.patch_all() -gevent.monkey.patch_all() +import zmq.green as zmq from typing import List, Any diff --git a/ait/core/server/handlers/ccsds_packet_handler.py b/ait/core/server/handlers/ccsds_packet_handler.py index f9335e89..73c02288 100644 --- a/ait/core/server/handlers/ccsds_packet_handler.py +++ b/ait/core/server/handlers/ccsds_packet_handler.py @@ -42,10 +42,8 @@ def __init__(self, input_type=None, output_type=None, **kwargs): tlm_dict = tlm.getDefaultDict() for packet_name in self.packet_types.values(): if packet_name not in tlm_dict.keys(): - msg = "CCSDSPacketHandler: Packet name {} not present in telemetry dictionary.".format( - packet_name - ) - msg += " Available packet types are {}".format(tlm_dict.keys()) + msg = f"CCSDSPacketHandler: Packet name {packet_name} not present in telemetry dictionary." + msg += f" Available packet types are {tlm_dict.keys()}" raise ValueError(msg) def handle(self, input_data): @@ -59,24 +57,20 @@ def handle(self, input_data): # Check if packet length is at least 7 bytes primary_header_length = 6 if len(input_data) < primary_header_length + 1: - ait.core.log.info( + ait.core.log.error( "CCSDSPacketHandler: Received packet length is less than minimum of 7 bytes." ) return # Extract APID from packet - packet_apid = str(bin(int(binascii.hexlify(input_data[0:2]), 16) & 0x07FF))[ - 2: - ].zfill(11) + packet_apid = str(bin(int(binascii.hexlify(input_data[0:2]), 16) & 0x07FF))[2:].zfill(11) # Check if packet_apid matches with an APID in the config config_apid = self.comp_apid(packet_apid) if not config_apid: - msg = "CCSDSPacketHandler: Packet APID {} not present in config.".format( - packet_apid - ) - msg += " Available packet APIDs are {}".format(self.packet_types.keys()) - ait.core.log.info(msg) + msg = f"CCSDSPacketHandler: Packet APID {packet_apid} not present in config." + msg += f" Available packet APIDs are {self.packet_types.keys()}" + ait.core.log.error(msg) return # Map APID to packet name in config to get UID from telemetry dictionary @@ -87,7 +81,7 @@ def handle(self, input_data): # Extract user data field from packet packet_data_length = int(binascii.hexlify(input_data[4:6]), 16) + 1 if len(input_data) < primary_header_length + packet_data_length: - ait.core.log.info( + ait.core.log.error( "CCSDSPacketHandler: Packet data length is less than stated length in packet primary header." ) return diff --git a/ait/core/server/handlers/packet_handler.py b/ait/core/server/handlers/packet_handler.py index 1ec845dc..b32ff288 100644 --- a/ait/core/server/handlers/packet_handler.py +++ b/ait/core/server/handlers/packet_handler.py @@ -19,27 +19,48 @@ def __init__(self, input_type=None, output_type=None, **kwargs): If packet is specified but not present in default tlm dict. """ super(PacketHandler, self).__init__(input_type, output_type) - self.packet = kwargs.get("packet", None) + self.packet_type = kwargs.get("packet", None) + self.tlm_dict = tlm.getDefaultDict() - if not self.packet: - msg = 'PacketHandler: No packet name provided in handler config as key "packet"' + if not self.packet_type: + msg = f'PacketHandler: No packet type provided in handler config as key "packet"' raise ValueError(msg) - tlm_dict = tlm.getDefaultDict() - if self.packet not in tlm_dict: - msg = "PacketHandler: Packet name {} not present in telemetry dictionary".format( - self.packet - ) - msg += " Available packet types are {}".format(tlm_dict.keys()) + if self.packet_type not in self.tlm_dict: + msg = f"PacketHandler: Packet name '{self.packet_type}' not present in telemetry dictionary." + msg += f" Available packet types are {self.tlm_dict.keys()}" raise ValueError(msg) - self._pkt_defn = tlm_dict[self.packet] + self._pkt_defn = self.tlm_dict[self.packet_type] - def handle(self, input_data): + def get_packet_lengths(self): + """ + Makes a dictionary of packet.name : number of bytes in the packet + e.g. 'Ethernet_HS_Packet': 37 + + Return: dictionary + + """ + pkt_len_dict = {} + for i in self.tlm_dict.keys(): + pkt_len_dict[i] = self.tlm_dict[i].nbytes + + return pkt_len_dict + + def handle(self, packet): """ Params: - input_data: message received by stream + packet: message received by stream (packet) Returns: tuple of packet UID and message received by stream """ - return pickle.dumps((self._pkt_defn.uid, input_data), 2) + + # TODO validate the packet + + defined_packet_lengths = self.get_packet_lengths() + + if defined_packet_lengths[self.packet_type] != packet.nbytes: + msg = f"PacketHandler: Packet length of packet does not match packet definition." + raise ValueError(msg) + + return pickle.dumps((self._pkt_defn.uid, packet), 2) diff --git a/ait/core/server/server.py b/ait/core/server/server.py index 29bb8e6d..55fd3b35 100644 --- a/ait/core/server/server.py +++ b/ait/core/server/server.py @@ -54,15 +54,15 @@ def __init__(self): def wait(self): """ - Starts all greenlets and plugin-pocesses for concurrent processing. + Starts all greenlets and plugin-processes for concurrent processing. Joins over all greenlets that are not servers. """ - # Start all of the greenlets managed by this process + # Start all greenlets managed by this process for greenlet in self.greenlets + self.servers: log.info(f"Starting {greenlet} greenlet...") greenlet.start() - # Start all of the separate plugin processes + # Start all separate plugin processes for plugin_process in self.plugin_processes: log.info(f"Spawning {plugin_process} process...") plugin_process.spawn_process() diff --git a/ait/core/tlm.py b/ait/core/tlm.py index 45e0fa74..d1204770 100644 --- a/ait/core/tlm.py +++ b/ait/core/tlm.py @@ -55,7 +55,6 @@ def __getitem__(self, key): """Returns the words in this wordarray at the given Python slice or word at the given integer index.""" length = len(self) - if isinstance(key, slice): return [self[n] for n in range(*key.indices(length))] @@ -371,6 +370,7 @@ def validate(self, value, messages=None): Validation error messages are appended to an optional messages array. """ + valid = True primitive = value @@ -520,7 +520,8 @@ def validate(self, messages=None): Validation error messages are appended to an optional messages array. """ - return self._defn.validate(self, messages) + + # return self._defn.validate(self, messages) class PacketContext: diff --git a/tests/ait/core/server/test_handler.py b/tests/ait/core/server/test_handler.py index f4d32252..1aff10b4 100644 --- a/tests/ait/core/server/test_handler.py +++ b/tests/ait/core/server/test_handler.py @@ -1,4 +1,5 @@ import pickle +import pytest import unittest from unittest import mock @@ -14,7 +15,7 @@ def test_ccsds_packet_length(self): handler = CCSDSPacketHandler(packet_types={"01011100111": "CCSDS_HEADER"}) data = bytearray(b"\x02\xE7\x40\x00\x00\x00") with self.assertLogs("ait", level="INFO") as cm: - result = handler.handle(data) + handler.handle(data) self.assertIn("less than minimum of 7 bytes", cm.output[0]) # Check if APID match between config and packet @@ -22,7 +23,7 @@ def test_ccsds_packet_apid(self): handler = CCSDSPacketHandler(packet_types={"00000000000": "CCSDS_HEADER"}) data = bytearray(b"\x02\xE7\x40\x00\x00\x00\x01") with self.assertLogs("ait", level="INFO") as cm: - result = handler.handle(data) + handler.handle(data) self.assertIn("not present in config", cm.output[0]) # Check packet length vs header reported length @@ -30,12 +31,16 @@ def test_ccsds_packet_header(self): handler = CCSDSPacketHandler(packet_types={"01011100111": "CCSDS_HEADER"}) data = bytearray(b"\x02\xE7\x40\x00\x00\x0F\x01") with self.assertLogs("ait", level="INFO") as cm: - result = handler.handle(data) + handler.handle(data) self.assertIn( "Packet data length is less than stated length in packet primary header", cm.output[0], ) + def test_packet_name_not_present(self): + with pytest.raises(ValueError): + CCSDSPacketHandler(packet_types={"01011100111": "CCSDS_"}) + # Check if dumped uid match expected tlm dictionary uid def test_ccsds_packet_uid(self): handler = CCSDSPacketHandler(packet_types={"01011100111": "CCSDS_HEADER"}) @@ -62,6 +67,59 @@ def test_execute_handler_returns_handle_return_on_input(self, handle_mock): assert returned == "SpecialReturn" +class TestHandlerClassWith1553HSPacket(object): + tlm_dict = tlm.getDefaultDict() + pkt_data = bytearray(b"\x02\xE7\x40\x00\x00\x00\x01") + pkt_1553 = tlm_dict['1553_HS_Packet'] + handler = PacketHandler(pkt_data, packet="1553_HS_Packet") + + def test_word_array(self): + packet = tlm.Packet(self.pkt_1553, self.pkt_data) + assert packet.words.__len__() == 3.5 + + def test_execute_handler_returns_handle_return_on_input(self): + packet = tlm.Packet(self.pkt_1553, self.pkt_data) + result = self.handler.handle(packet) + assert 'Ethernet 1553 packet' in str(result) + + # Test packet length by sending a Ethernet_HS_Packet to a 1553_HS_Packet Handler + def test_bad_packet_length(self): + ethernet_pkt = self.tlm_dict['Ethernet_HS_Packet'] + e_packet = tlm.Packet(ethernet_pkt, self.pkt_data) + with pytest.raises(ValueError): + self.handler.handle(e_packet) + + def test_packet_name_error_and_no_packet_type(self): + pkt_data = bytearray(b"\x02\xE7\x40\x00\x00\x00\x01") + with pytest.raises(ValueError): + PacketHandler(pkt_data, packet="1553_HS_Packe") + with pytest.raises(ValueError): + PacketHandler(pkt_data) + + +class TestHandlerClassWithEthernetHSPacket(object): + tlm_dict = tlm.getDefaultDict() + pkt_data = bytearray(b"\x02\xE7\x40\x00\x00\x00\x01\x07\x08\x0a") + ethernet_pkt = tlm_dict['Ethernet_HS_Packet'] + handler = PacketHandler(pkt_data, packet="Ethernet_HS_Packet") + + def test_word_array(self): + e_packet = tlm.Packet(self.ethernet_pkt, self.pkt_data) + assert e_packet.words.__len__() == 5 + + def test_execute_handler_returns_handle_return_on_input(self): + e_packet = tlm.Packet(self.ethernet_pkt, self.pkt_data) + result = self.handler.handle(e_packet) + assert 'Ethernet Health and Status Packet' in str(result) + + # Send a 1553 packet to an Ethernet_HS_Packet Handler + def test_bad_packet_length(self): + pkt_1553 = self.tlm_dict['1553_HS_Packet'] + packet = tlm.Packet(pkt_1553, self.pkt_data) + with pytest.raises(ValueError): + self.handler.handle(packet) + + class TestHandlerClassWithoutInputOutputTypes(object): handler = PacketHandler(packet="CCSDS_HEADER") From cedc7cb97931006e5eb3669f9c4b2dff463ea0f0 Mon Sep 17 00:00:00 2001 From: Jim Hofman Date: Thu, 6 Oct 2022 14:21:39 -0700 Subject: [PATCH 2/8] issue-368 test packet dats --- ait/core/server/handlers/packet_handler.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/ait/core/server/handlers/packet_handler.py b/ait/core/server/handlers/packet_handler.py index b32ff288..b19cba52 100644 --- a/ait/core/server/handlers/packet_handler.py +++ b/ait/core/server/handlers/packet_handler.py @@ -55,7 +55,7 @@ def handle(self, packet): tuple of packet UID and message received by stream """ - # TODO validate the packet + # TODO validate the packet (if this is the place to do the validation) defined_packet_lengths = self.get_packet_lengths() From ec2ebab4bf21583f610f728a9f5f7a9575388d35 Mon Sep 17 00:00:00 2001 From: Jim Hofman Date: Tue, 11 Oct 2022 14:35:08 -0700 Subject: [PATCH 3/8] issue-368 review fixes --- ait/core/server/handlers/packet_handler.py | 30 +++++----------------- ait/core/tlm.py | 2 +- 2 files changed, 7 insertions(+), 25 deletions(-) diff --git a/ait/core/server/handlers/packet_handler.py b/ait/core/server/handlers/packet_handler.py index b19cba52..1fde49e0 100644 --- a/ait/core/server/handlers/packet_handler.py +++ b/ait/core/server/handlers/packet_handler.py @@ -19,33 +19,19 @@ def __init__(self, input_type=None, output_type=None, **kwargs): If packet is specified but not present in default tlm dict. """ super(PacketHandler, self).__init__(input_type, output_type) - self.packet_type = kwargs.get("packet", None) + self.packet_name = kwargs.get("packet", None) self.tlm_dict = tlm.getDefaultDict() - if not self.packet_type: + if not self.packet_name: msg = f'PacketHandler: No packet type provided in handler config as key "packet"' raise ValueError(msg) - if self.packet_type not in self.tlm_dict: - msg = f"PacketHandler: Packet name '{self.packet_type}' not present in telemetry dictionary." + if self.packet_name not in self.tlm_dict: + msg = f"PacketHandler: Packet name '{self.packet_name}' not present in telemetry dictionary." msg += f" Available packet types are {self.tlm_dict.keys()}" raise ValueError(msg) - self._pkt_defn = self.tlm_dict[self.packet_type] - - def get_packet_lengths(self): - """ - Makes a dictionary of packet.name : number of bytes in the packet - e.g. 'Ethernet_HS_Packet': 37 - - Return: dictionary - - """ - pkt_len_dict = {} - for i in self.tlm_dict.keys(): - pkt_len_dict[i] = self.tlm_dict[i].nbytes - - return pkt_len_dict + self._pkt_defn = self.tlm_dict[self.packet_name] def handle(self, packet): """ @@ -55,11 +41,7 @@ def handle(self, packet): tuple of packet UID and message received by stream """ - # TODO validate the packet (if this is the place to do the validation) - - defined_packet_lengths = self.get_packet_lengths() - - if defined_packet_lengths[self.packet_type] != packet.nbytes: + if self._pkt_defn.nbytes != packet.nbytes: msg = f"PacketHandler: Packet length of packet does not match packet definition." raise ValueError(msg) diff --git a/ait/core/tlm.py b/ait/core/tlm.py index d1204770..38f5c054 100644 --- a/ait/core/tlm.py +++ b/ait/core/tlm.py @@ -521,7 +521,7 @@ def validate(self, messages=None): array. """ - # return self._defn.validate(self, messages) + return self._defn.validate(self, messages) class PacketContext: From 921b1ad5e5fb9dffc88273a0afb718ca4e405db8 Mon Sep 17 00:00:00 2001 From: Jim Hofman Date: Wed, 12 Oct 2022 11:27:27 -0700 Subject: [PATCH 4/8] issue-368 modify comment --- ait/core/server/handlers/packet_handler.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/ait/core/server/handlers/packet_handler.py b/ait/core/server/handlers/packet_handler.py index 1fde49e0..e081b41f 100644 --- a/ait/core/server/handlers/packet_handler.py +++ b/ait/core/server/handlers/packet_handler.py @@ -42,7 +42,7 @@ def handle(self, packet): """ if self._pkt_defn.nbytes != packet.nbytes: - msg = f"PacketHandler: Packet length of packet does not match packet definition." + msg = f"PacketHandler: Packet data length does not match packet definition." raise ValueError(msg) return pickle.dumps((self._pkt_defn.uid, packet), 2) From 4e1218040dd6fa868d3adc768e042aa3f85e7940 Mon Sep 17 00:00:00 2001 From: Jim Hofman Date: Mon, 17 Oct 2022 14:57:06 -0700 Subject: [PATCH 5/8] Addressed errors Michael pointed out --- ait/core/server/handlers/packet_handler.py | 47 +++++--- tests/ait/core/server/test_handler.py | 127 +++++++++++++-------- 2 files changed, 110 insertions(+), 64 deletions(-) diff --git a/ait/core/server/handlers/packet_handler.py b/ait/core/server/handlers/packet_handler.py index e081b41f..4e654ff1 100644 --- a/ait/core/server/handlers/packet_handler.py +++ b/ait/core/server/handlers/packet_handler.py @@ -1,48 +1,63 @@ import pickle from ait.core.server.handler import Handler -from ait.core import tlm +from ait.core import tlm, log class PacketHandler(Handler): def __init__(self, input_type=None, output_type=None, **kwargs): """ + This handler provides a way to accept multiple packet types + (e.g. '1553_HS_Packet' and 'Ethernet_HS_Packet') single stream + and have them be processed. This handler takes a string of + raw binary data containing the packet data. It gets the UID from + the telemetry dictionary. A tuple of the UID and user data + field is returned. + Params: input_type: (optional) Specifies expected input type, used to validate handler workflow. Defaults to None. output_type: (optional) Specifies expected output type, used to validate handler workflow. Defaults to None **kwargs: - packet: (required) Name of packet, present in default tlm dict. + packet_type: (required) Type of packet (e.g. '1553_HS_Packet', 'Ethernet_HS_Packet') + Present in default tlm dict. Raises: - ValueError: If packet is not present in kwargs. + ValueError: If packet type is not present in kwargs. If packet is specified but not present in default tlm dict. - """ + """ super(PacketHandler, self).__init__(input_type, output_type) - self.packet_name = kwargs.get("packet", None) + self.packet_type = kwargs.get("packet_type", None) self.tlm_dict = tlm.getDefaultDict() - if not self.packet_name: - msg = f'PacketHandler: No packet type provided in handler config as key "packet"' + if not self.packet_type: + msg = f'PacketHandler: No packet type provided in handler config as key "packet_type"' raise ValueError(msg) - if self.packet_name not in self.tlm_dict: - msg = f"PacketHandler: Packet name '{self.packet_name}' not present in telemetry dictionary." + if self.packet_type not in self.tlm_dict: + msg = f"PacketHandler: Packet name '{self.packet_type}' not present in telemetry dictionary." msg += f" Available packet types are {self.tlm_dict.keys()}" raise ValueError(msg) - self._pkt_defn = self.tlm_dict[self.packet_name] + self._pkt_defn = self.tlm_dict[self.packet_type] - def handle(self, packet): + def handle(self, input_data): """ + Test the input_data length against the length in the telemetry + Params: - packet: message received by stream (packet) + input_data : byteArray + message received by stream (raw data) Returns: tuple of packet UID and message received by stream """ - if self._pkt_defn.nbytes != packet.nbytes: - msg = f"PacketHandler: Packet data length does not match packet definition." - raise ValueError(msg) + if self._pkt_defn.nbytes != len(input_data): + log.error( + f"PacketHandler: Packet data length does not match packet definition." + ) + return 0 + else: + return pickle.dumps((self._pkt_defn.uid, input_data), 2) - return pickle.dumps((self._pkt_defn.uid, packet), 2) + return pickle.dumps((self._pkt_defn.uid, input_data), 2) diff --git a/tests/ait/core/server/test_handler.py b/tests/ait/core/server/test_handler.py index 1aff10b4..cfc7655d 100644 --- a/tests/ait/core/server/test_handler.py +++ b/tests/ait/core/server/test_handler.py @@ -1,4 +1,5 @@ import pickle +import _pickle import pytest import unittest from unittest import mock @@ -9,7 +10,6 @@ class TestCCSDSPacketCheck(unittest.TestCase): - # Check if packet length is at least 7 bytes def test_ccsds_packet_length(self): handler = CCSDSPacketHandler(packet_types={"01011100111": "CCSDS_HEADER"}) @@ -52,76 +52,106 @@ def test_ccsds_packet_uid(self): self.assertEqual(packet_uid, pickle.loads(result)[0]) -class TestHandlerClassWithInputOutputTypes(object): - handler = PacketHandler(packet="CCSDS_HEADER", input_type="int", output_type="str") +class TestCCSDSHandlerClassWithInputOutputTypes(object): + handler = CCSDSPacketHandler( + packet_types={"01011100111": "CCSDS_HEADER"}, + input_type="int", + output_type="str", + ) def test_handler_creation(self): assert self.handler.input_type is "int" assert self.handler.output_type is "str" @mock.patch( - "ait.core.server.handlers.PacketHandler.handle", return_value="SpecialReturn" + "ait.core.server.handlers.CCSDSPacketHandler.handle", + return_value="SpecialReturn", ) def test_execute_handler_returns_handle_return_on_input(self, handle_mock): - returned = self.handler.handle("2") + data = bytearray(b"\x02\xE7\x40\x00\x00\x00\x01") + returned = self.handler.handle(data) assert returned == "SpecialReturn" -class TestHandlerClassWith1553HSPacket(object): +class TestCCSDSHandlerClassWithoutInputOutputTypes(object): + handler = CCSDSPacketHandler(packet_types={"01011100111": "CCSDS_HEADER"}) + + def test_ccsds_handler_default_params(self): + assert self.handler.input_type is None + assert self.handler.output_type is None + + @mock.patch( + "ait.core.server.handlers.CCSDSPacketHandler.handle", + return_value="SpecialReturn", + ) + def test_execute_handler_returns_handle_return_on_input(self, handle_mock): + data = bytearray(b"\x02\xE7\x40\x00\x00\x00\x01") + returned = self.handler.handle(data) + assert returned == "SpecialReturn" + + def test_handler_repr(self): + assert self.handler.__repr__() == "" + + +class TestHandlerClassWith1553HSPacket(unittest.TestCase): tlm_dict = tlm.getDefaultDict() - pkt_data = bytearray(b"\x02\xE7\x40\x00\x00\x00\x01") + pkt_data = bytearray(b"\x02\xE7\x40\x00\x00\x00\x01\x02\x03\x04") pkt_1553 = tlm_dict['1553_HS_Packet'] - handler = PacketHandler(pkt_data, packet="1553_HS_Packet") + handler = PacketHandler(packet_type="1553_HS_Packet") def test_word_array(self): packet = tlm.Packet(self.pkt_1553, self.pkt_data) - assert packet.words.__len__() == 3.5 + assert packet.words.__len__() == self.pkt_1553.nbytes/2 - def test_execute_handler_returns_handle_return_on_input(self): - packet = tlm.Packet(self.pkt_1553, self.pkt_data) - result = self.handler.handle(packet) - assert 'Ethernet 1553 packet' in str(result) + def test_1553_uid(self): + packet_uid = self.tlm_dict["1553_HS_Packet"].uid + result = self.handler.handle(self.pkt_data) + self.assertEqual(packet_uid, pickle.loads(result)[0]) - # Test packet length by sending a Ethernet_HS_Packet to a 1553_HS_Packet Handler + # Send only 5 bytes 1553 Packet expects 10 bytes def test_bad_packet_length(self): - ethernet_pkt = self.tlm_dict['Ethernet_HS_Packet'] - e_packet = tlm.Packet(ethernet_pkt, self.pkt_data) - with pytest.raises(ValueError): - self.handler.handle(e_packet) + pkt_data = bytearray(b"\x02\xE7\x40\x00\x00") + with self.assertLogs("ait", level="INFO") as cm: + self.handler.handle(pkt_data) + self.assertIn( + "Packet data length does not match packet definition.", + cm.output[0], + ) def test_packet_name_error_and_no_packet_type(self): - pkt_data = bytearray(b"\x02\xE7\x40\x00\x00\x00\x01") with pytest.raises(ValueError): - PacketHandler(pkt_data, packet="1553_HS_Packe") - with pytest.raises(ValueError): - PacketHandler(pkt_data) + PacketHandler(packet_type="") -class TestHandlerClassWithEthernetHSPacket(object): +class TestHandlerClassWithEthernetHSPacket(unittest.TestCase): tlm_dict = tlm.getDefaultDict() - pkt_data = bytearray(b"\x02\xE7\x40\x00\x00\x00\x01\x07\x08\x0a") - ethernet_pkt = tlm_dict['Ethernet_HS_Packet'] - handler = PacketHandler(pkt_data, packet="Ethernet_HS_Packet") + pkt_data = bytearray(b"\x02\xE7\x40\x00\x00\x00\x01\x40\x00\x03\x02\xE7\x40\x00\x00\x00\x01\x40\x00\x03" + b"\x02\xE7\x40\x00\x00\x00\x01\x40\x00\x03\x02\xE7\x40\x00\x00\x00\x01") + ethernet_pkt_def = tlm_dict['Ethernet_HS_Packet'] + handler = PacketHandler(packet_type="Ethernet_HS_Packet") def test_word_array(self): - e_packet = tlm.Packet(self.ethernet_pkt, self.pkt_data) - assert e_packet.words.__len__() == 5 + e_packet = tlm.Packet(self.ethernet_pkt_def, self.pkt_data) + assert e_packet.words.__len__() == self.ethernet_pkt_def.nbytes/2.0 - def test_execute_handler_returns_handle_return_on_input(self): - e_packet = tlm.Packet(self.ethernet_pkt, self.pkt_data) - result = self.handler.handle(e_packet) - assert 'Ethernet Health and Status Packet' in str(result) + def test_1553_uid(self): + packet_uid = self.tlm_dict["Ethernet_HS_Packet"].uid + result = self.handler.handle(self.pkt_data) + self.assertEqual(packet_uid, pickle.loads(result)[0]) - # Send a 1553 packet to an Ethernet_HS_Packet Handler + # Ethernet packet expects 37 bytes 1552 expects 10 def test_bad_packet_length(self): - pkt_1553 = self.tlm_dict['1553_HS_Packet'] - packet = tlm.Packet(pkt_1553, self.pkt_data) - with pytest.raises(ValueError): - self.handler.handle(packet) + pkt_data = bytearray(b"\x02\xE7\x40\x00\x00\x00\x01\x07\x08\x0a") + with self.assertLogs("ait", level="INFO") as cm: + self.handler.handle(pkt_data) + self.assertIn( + "Packet data length does not match packet definition.", + cm.output[0], + ) class TestHandlerClassWithoutInputOutputTypes(object): - handler = PacketHandler(packet="CCSDS_HEADER") + handler = PacketHandler(packet_type="Ethernet_HS_Packet") def test_handler_default_params(self): assert self.handler.input_type is None @@ -138,9 +168,9 @@ def test_handler_repr(self): assert self.handler.__repr__() == "" -class TestCCSDSHandlerClassWithInputOutputTypes(object): - handler = CCSDSPacketHandler( - packet_types={"01011100111": "CCSDS_HEADER"}, +class TestHandlerClassWithInputOutputTypes(object): + handler = PacketHandler( + packet_type='1553_HS_Packet', input_type="int", output_type="str", ) @@ -150,30 +180,31 @@ def test_handler_creation(self): assert self.handler.output_type is "str" @mock.patch( - "ait.core.server.handlers.CCSDSPacketHandler.handle", + "ait.core.server.handlers.PacketHandler.handle", return_value="SpecialReturn", ) def test_execute_handler_returns_handle_return_on_input(self, handle_mock): - data = bytearray(b"\x02\xE7\x40\x00\x00\x00\x01") + data = bytearray(b"\x02\xE7\x40\x00\x00\x00\x01\x02\x03\x04") returned = self.handler.handle(data) assert returned == "SpecialReturn" -class TestCCSDSHandlerClassWithoutInputOutputTypes(object): - handler = CCSDSPacketHandler(packet_types={"01011100111": "CCSDS_HEADER"}) +class TestHandlerClassWithoutInputOutputTypes(object): + handler = PacketHandler(packet_type="Ethernet_HS_Packet") def test_ccsds_handler_default_params(self): assert self.handler.input_type is None assert self.handler.output_type is None @mock.patch( - "ait.core.server.handlers.CCSDSPacketHandler.handle", + "ait.core.server.handlers.PacketHandler.handle", return_value="SpecialReturn", ) def test_execute_handler_returns_handle_return_on_input(self, handle_mock): - data = bytearray(b"\x02\xE7\x40\x00\x00\x00\x01") + # Note: Using 'mock' handler, the data will not be tested for length. + data = bytearray(b"\x02\xE7\x40\x00\x00\x00\x01\x02\x03\x04") returned = self.handler.handle(data) assert returned == "SpecialReturn" def test_handler_repr(self): - assert self.handler.__repr__() == "" + assert self.handler.__repr__() == "" From e58e893870292e16aafee910c9088810b5d59c65 Mon Sep 17 00:00:00 2001 From: Jim Hofman Date: Mon, 17 Oct 2022 15:13:43 -0700 Subject: [PATCH 6/8] Had to clear up handling of kwargs in packet_handler.py and unit tests --- ait/core/server/handlers/packet_handler.py | 6 +++--- config/leapseconds.dat | Bin 570 -> 570 bytes tests/ait/core/server/test_handler.py | 12 ++++++------ 3 files changed, 9 insertions(+), 9 deletions(-) diff --git a/ait/core/server/handlers/packet_handler.py b/ait/core/server/handlers/packet_handler.py index 4e654ff1..287cfeb0 100644 --- a/ait/core/server/handlers/packet_handler.py +++ b/ait/core/server/handlers/packet_handler.py @@ -20,18 +20,18 @@ def __init__(self, input_type=None, output_type=None, **kwargs): output_type: (optional) Specifies expected output type, used to validate handler workflow. Defaults to None **kwargs: - packet_type: (required) Type of packet (e.g. '1553_HS_Packet', 'Ethernet_HS_Packet') + packet: (required) Type of packet (e.g. '1553_HS_Packet', 'Ethernet_HS_Packet') Present in default tlm dict. Raises: ValueError: If packet type is not present in kwargs. If packet is specified but not present in default tlm dict. """ super(PacketHandler, self).__init__(input_type, output_type) - self.packet_type = kwargs.get("packet_type", None) + self.packet_type = kwargs.get("packet", None) self.tlm_dict = tlm.getDefaultDict() if not self.packet_type: - msg = f'PacketHandler: No packet type provided in handler config as key "packet_type"' + msg = f'PacketHandler: No packet type provided in handler config as key {self.packet_type}' raise ValueError(msg) if self.packet_type not in self.tlm_dict: diff --git a/config/leapseconds.dat b/config/leapseconds.dat index 01a9b653953e5ce5bed641a2fad64f9ef05014a3..815ff2d1b92b27875f79c967e18c365b6b0ec1d2 100644 GIT binary patch delta 12 TcmdnRvWsPc7UT1c+Wbra9qa@Q delta 12 TcmdnRvWsPc7UQ#x+Wbra9p?lK diff --git a/tests/ait/core/server/test_handler.py b/tests/ait/core/server/test_handler.py index cfc7655d..1cb040de 100644 --- a/tests/ait/core/server/test_handler.py +++ b/tests/ait/core/server/test_handler.py @@ -97,7 +97,7 @@ class TestHandlerClassWith1553HSPacket(unittest.TestCase): tlm_dict = tlm.getDefaultDict() pkt_data = bytearray(b"\x02\xE7\x40\x00\x00\x00\x01\x02\x03\x04") pkt_1553 = tlm_dict['1553_HS_Packet'] - handler = PacketHandler(packet_type="1553_HS_Packet") + handler = PacketHandler(packet="1553_HS_Packet") def test_word_array(self): packet = tlm.Packet(self.pkt_1553, self.pkt_data) @@ -120,7 +120,7 @@ def test_bad_packet_length(self): def test_packet_name_error_and_no_packet_type(self): with pytest.raises(ValueError): - PacketHandler(packet_type="") + PacketHandler(packet="") class TestHandlerClassWithEthernetHSPacket(unittest.TestCase): @@ -128,7 +128,7 @@ class TestHandlerClassWithEthernetHSPacket(unittest.TestCase): pkt_data = bytearray(b"\x02\xE7\x40\x00\x00\x00\x01\x40\x00\x03\x02\xE7\x40\x00\x00\x00\x01\x40\x00\x03" b"\x02\xE7\x40\x00\x00\x00\x01\x40\x00\x03\x02\xE7\x40\x00\x00\x00\x01") ethernet_pkt_def = tlm_dict['Ethernet_HS_Packet'] - handler = PacketHandler(packet_type="Ethernet_HS_Packet") + handler = PacketHandler(packet="Ethernet_HS_Packet") def test_word_array(self): e_packet = tlm.Packet(self.ethernet_pkt_def, self.pkt_data) @@ -151,7 +151,7 @@ def test_bad_packet_length(self): class TestHandlerClassWithoutInputOutputTypes(object): - handler = PacketHandler(packet_type="Ethernet_HS_Packet") + handler = PacketHandler(packet="Ethernet_HS_Packet") def test_handler_default_params(self): assert self.handler.input_type is None @@ -170,7 +170,7 @@ def test_handler_repr(self): class TestHandlerClassWithInputOutputTypes(object): handler = PacketHandler( - packet_type='1553_HS_Packet', + packet='1553_HS_Packet', input_type="int", output_type="str", ) @@ -190,7 +190,7 @@ def test_execute_handler_returns_handle_return_on_input(self, handle_mock): class TestHandlerClassWithoutInputOutputTypes(object): - handler = PacketHandler(packet_type="Ethernet_HS_Packet") + handler = PacketHandler(packet="Ethernet_HS_Packet") def test_ccsds_handler_default_params(self): assert self.handler.input_type is None From 613da4094b2403c3cc662eaf93f03f6aa5c45831 Mon Sep 17 00:00:00 2001 From: Jim Hofman Date: Mon, 17 Oct 2022 15:25:29 -0700 Subject: [PATCH 7/8] added one test --- tests/ait/core/server/test_handler.py | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/tests/ait/core/server/test_handler.py b/tests/ait/core/server/test_handler.py index 1cb040de..3fa1f5fe 100644 --- a/tests/ait/core/server/test_handler.py +++ b/tests/ait/core/server/test_handler.py @@ -122,6 +122,10 @@ def test_packet_name_error_and_no_packet_type(self): with pytest.raises(ValueError): PacketHandler(packet="") + def test_handler_class_with_bad_packet_type(self): + with pytest.raises(ValueError): + PacketHandler(packet="Ethernet_Packet") + class TestHandlerClassWithEthernetHSPacket(unittest.TestCase): tlm_dict = tlm.getDefaultDict() From 4aca498e39179748b44f32030c95da3cf069c3b6 Mon Sep 17 00:00:00 2001 From: Jim Hofman Date: Fri, 28 Oct 2022 14:25:24 -0700 Subject: [PATCH 8/8] issue_368 make pull request changes --- ait/core/server/handlers/packet_handler.py | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/ait/core/server/handlers/packet_handler.py b/ait/core/server/handlers/packet_handler.py index 287cfeb0..b1d88cad 100644 --- a/ait/core/server/handlers/packet_handler.py +++ b/ait/core/server/handlers/packet_handler.py @@ -27,19 +27,19 @@ def __init__(self, input_type=None, output_type=None, **kwargs): If packet is specified but not present in default tlm dict. """ super(PacketHandler, self).__init__(input_type, output_type) - self.packet_type = kwargs.get("packet", None) + self.packet_name = kwargs.get("packet", None) self.tlm_dict = tlm.getDefaultDict() - if not self.packet_type: - msg = f'PacketHandler: No packet type provided in handler config as key {self.packet_type}' + if not self.packet_name: + msg = f'PacketHandler: No packet type provided in handler config as key {self.packet_name}' raise ValueError(msg) - if self.packet_type not in self.tlm_dict: - msg = f"PacketHandler: Packet name '{self.packet_type}' not present in telemetry dictionary." + if self.packet_name not in self.tlm_dict: + msg = f"PacketHandler: Packet name '{self.packet_name}' not present in telemetry dictionary." msg += f" Available packet types are {self.tlm_dict.keys()}" raise ValueError(msg) - self._pkt_defn = self.tlm_dict[self.packet_type] + self._pkt_defn = self.tlm_dict[self.packet_name] def handle(self, input_data): """