From cf24355716a12b2dabf5fae3eb476ab2affc6536 Mon Sep 17 00:00:00 2001 From: Aliaksandr Nikitsin Date: Wed, 3 Jun 2026 20:30:27 +0200 Subject: [PATCH 1/6] device with report model --- framework/python/src/common/device.py | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/framework/python/src/common/device.py b/framework/python/src/common/device.py index b86dfebe0..f5082e828 100644 --- a/framework/python/src/common/device.py +++ b/framework/python/src/common/device.py @@ -149,3 +149,9 @@ def __setattr__(self, name: str, value: any) -> None: # Update the last_updated timestamp super().__setattr__('modified_at', datetime.now()) super().__setattr__(name, value) + + +@dataclass +class DeviceWithReport(): + device: Device | None = None + report: TestReport | None = None From a7f284bf7cbeda08bf2ec80e2d12e8c3fc0d2c22 Mon Sep 17 00:00:00 2001 From: Aliaksandr Nikitsin Date: Wed, 3 Jun 2026 20:31:07 +0200 Subject: [PATCH 2/6] find report new approach --- framework/python/src/core/session.py | 12 +++++++++++- 1 file changed, 11 insertions(+), 1 deletion(-) diff --git a/framework/python/src/core/session.py b/framework/python/src/core/session.py index a01efcd9c..43918cecd 100644 --- a/framework/python/src/core/session.py +++ b/framework/python/src/core/session.py @@ -21,7 +21,7 @@ from common import util, logger, mqtt from common.risk_profile import RiskProfile from common.statuses import TestrunStatus, TestResult, TestrunResult -from common.device import Device +from common.device import Device, DeviceWithReport from net_orc.ip_control import IPControl # Certificate dependencies @@ -393,6 +393,16 @@ def get_device_by_mac_addr(self, mac_addr_simmplified: str) -> Device | None: def get_device_repository(self): return self._device_repository + def get_report(self, folder_name: str) -> DeviceWithReport: + device_with_report = DeviceWithReport() + for device in self._device_repository: + device_reports = device.get_reports() + for report in device_reports: + if report.get_folder_name() == folder_name: + device_with_report.device = device + device_with_report.report = report + return device_with_report + def add_device(self, device): self._device_repository.append(device) From e8f1978543e77a244f84e0715fdf66d030bb55b9 Mon Sep 17 00:00:00 2001 From: Aliaksandr Nikitsin Date: Wed, 3 Jun 2026 20:31:53 +0200 Subject: [PATCH 3/6] change test folder path --- framework/python/src/test_orc/test_orchestrator.py | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/framework/python/src/test_orc/test_orchestrator.py b/framework/python/src/test_orc/test_orchestrator.py index eef767a0f..bc19a26fb 100644 --- a/framework/python/src/test_orc/test_orchestrator.py +++ b/framework/python/src/test_orc/test_orchestrator.py @@ -400,9 +400,10 @@ def _regenerate_report_files(self, device: Device, report: TestReport) -> str: # Report files path report_dir = os.path.join(self._root_path, REPORTS_FOLDER) report_dir = os.path.join(report_dir, report.get_folder_name()) + test_folder_name = report.get_folder_name().split("_")[0] test_path = os.path.join( report_dir, - f'test/{device.mac_addr.replace(":", "")}' + f'test/{test_folder_name}' ) try: # Copy the original report for comparison From 2881781b24545b9d12bfc8ee7b78ceb53b4597e1 Mon Sep 17 00:00:00 2001 From: Aliaksandr Nikitsin Date: Wed, 3 Jun 2026 20:34:38 +0200 Subject: [PATCH 4/6] change reports search approach --- framework/python/src/api/api.py | 52 ++++++++++----------------------- 1 file changed, 15 insertions(+), 37 deletions(-) diff --git a/framework/python/src/api/api.py b/framework/python/src/api/api.py index f0910eb02..1c5a2a01f 100644 --- a/framework/python/src/api/api.py +++ b/framework/python/src/api/api.py @@ -460,21 +460,13 @@ async def get_reports(self): async def delete_report(self, response: Response, report_name: str): - mac = report_name.split("_")[0] - device = self._session.get_device_by_mac_addr(mac) - - # If the device not found - if device is None: - LOGGER.info("Device not found, returning 404") - response.status_code = 404 - return self._generate_msg(False, "Device not found") - - report = device.get_report_by_folder_name(report_name) - LOGGER.debug(f"Looking for report with name {report_name}") - if not report: + device_with_report = self._session.get_report(report_name) + if device_with_report.device is None or device_with_report.report is None: LOGGER.info("Report could not be found, returning 404") response.status_code = 404 - return self._generate_msg(False, "Report not found") + return self._generate_msg(False, "Report not found from list") + device = device_with_report.device + report = device_with_report.report if self._testrun.delete_report(device, report): return self._generate_msg(True, "Deleted report") @@ -680,22 +672,13 @@ async def edit_device(self, request: Request, response: Response): async def get_report(self, response: Response, report_name): """Serve report pdf file for a given report name""" - mac = report_name.split("_")[0] - device = self._session.get_device_by_mac_addr(mac) - - # If the device not found - if device is None: - LOGGER.info("Device not found, returning 404") - response.status_code = 404 - return self._generate_msg(False, "Device not found") - - report = device.get_report_by_folder_name(report_name) - LOGGER.debug(f"Looking for report with name {report_name}") - if not report: + device_with_report = self._session.get_report(report_name) + if device_with_report.device is None or device_with_report.report is None: LOGGER.info("Report could not be found, returning 404") response.status_code = 404 - return self._generate_msg(False, "Report could not be found") - + return self._generate_msg(False, "Report not found from list") + device = device_with_report.device + report = device_with_report.report # Regenerate the pdf if the device profile has been updated test_orc = self._get_testrun().get_test_orc() @@ -738,18 +721,13 @@ async def get_results( pass # Check if device exists - mac = report_name.split("_")[0] - device = self._session.get_device_by_mac_addr(mac) - if device is None: - response.status_code = status.HTTP_404_NOT_FOUND - return self._generate_msg(False, - "Device not found") - report = device.get_report_by_folder_name(report_name) - LOGGER.debug(f"Looking for report with name {report_name}") - if not report: + device_with_report = self._session.get_report(report_name) + if device_with_report.device is None or device_with_report.report is None: LOGGER.info("Report could not be found, returning 404") response.status_code = 404 - return self._generate_msg(False, "Report could not be found") + return self._generate_msg(False, "Report not found from list") + device = device_with_report.device + report = device_with_report.report zip_file_path = self._get_testrun().get_test_orc().zip_results( device, report, profile) From 43e22be8aabad95f8de4c4be47bce1c1e000ec38 Mon Sep 17 00:00:00 2001 From: Aliaksandr Nikitsin Date: Wed, 3 Jun 2026 20:40:03 +0200 Subject: [PATCH 5/6] pylint --- framework/python/src/test_orc/test_orchestrator.py | 10 +++------- 1 file changed, 3 insertions(+), 7 deletions(-) diff --git a/framework/python/src/test_orc/test_orchestrator.py b/framework/python/src/test_orc/test_orchestrator.py index bc19a26fb..20ed052dc 100644 --- a/framework/python/src/test_orc/test_orchestrator.py +++ b/framework/python/src/test_orc/test_orchestrator.py @@ -396,19 +396,19 @@ def regenerate_pdf(self, device: Device, report: TestReport) -> str: return self._regenerate_report_files(device, report) def _regenerate_report_files(self, device: Device, report: TestReport) -> str: - '''Regenerate the report if the device profile has been updated''' + """Regenerate the report if the device profile has been updated""" # Report files path report_dir = os.path.join(self._root_path, REPORTS_FOLDER) report_dir = os.path.join(report_dir, report.get_folder_name()) test_folder_name = report.get_folder_name().split("_")[0] test_path = os.path.join( report_dir, - f'test/{test_folder_name}' + f"test/{test_folder_name}" ) try: # Copy the original report for comparison report_copy = copy.deepcopy(report) - # Update the report with 'additional_info' field + # Update the report with additional_info field report.update_device_info(device) device.export_config_json() # Overwrite report only if additional_info has been changed @@ -487,17 +487,13 @@ def _update_html_report(self, report: TestReport, html: str): if value_div: if "Manufacturer" in h4.string: value_div.string = manufacturer - LOGGER.debug(f"Updated manufacturer to '{value_div.string}'") elif "Model" in h4.string: value_div.string = model - LOGGER.debug(f"Updated model to '{value_div.string}'") all_header_info_divs = bs.find_all("div", class_="header-info") for header_info_div in all_header_info_divs: header_span = header_info_div.find_next_sibling("span") if header_span: header_span.string = title - LOGGER.debug(f"Updated sibling span to '{header_span.string}'") - return str(bs) def test_in_progress(self): From 6e7d41f842f939be1fda4b114d6632c54c68cd05 Mon Sep 17 00:00:00 2001 From: Aliaksandr Nikitsin Date: Wed, 3 Jun 2026 21:27:53 +0200 Subject: [PATCH 6/6] api tests --- testing/api/test_api.py | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/testing/api/test_api.py b/testing/api/test_api.py index 28c92467d..431aac56f 100644 --- a/testing/api/test_api.py +++ b/testing/api/test_api.py @@ -1104,7 +1104,7 @@ def test_delete_report_no_device(empty_devices_dir, testrun): # pylint: disable= assert "error" in response # Check if the correct error message returned - assert "Device not found" in response["error"] + assert "Report not found" in response["error"] @pytest.mark.parametrize("add_devices", [ ["device_1"] @@ -1167,13 +1167,13 @@ def test_get_report_not_found(empty_devices_dir, add_devices, testrun): # pylint assert "error" in response # Check if the correct error message is returned - assert "Report could not be found" in response["error"] + assert "Report not found from list" in response["error"] # Check if "error" in response assert "error" in response # Check if the correct error message returned - assert "Report could not be found" in response["error"] + assert "Report not found from list" in response["error"] def test_get_report_device_not_found(empty_devices_dir, testrun): # pylint: disable=W0613 """Test getting a report when the device is not found (404)""" @@ -1194,7 +1194,7 @@ def test_get_report_device_not_found(empty_devices_dir, testrun): # pylint: disa assert "error" in response # Check if the correct error message is returned - assert "Device not found" in response["error"] + assert "Report not found from list" in response["error"] def test_export_report_device_not_found(empty_devices_dir, create_report_folder, # pylint: disable=W0613 testrun): # pylint: disable=W0613 @@ -1219,7 +1219,7 @@ def test_export_report_device_not_found(empty_devices_dir, create_report_folder, assert "error" in response # Check if the correct error message is returned - assert "Device not found" in response["error"] + assert "Report not found from list" in response["error"] @pytest.mark.parametrize("add_devices", [ ["device_1"] @@ -1288,7 +1288,7 @@ def test_export_report_not_found(empty_devices_dir, add_devices, testrun): # pyl assert "error" in response # Check if the correct error message is returned - assert "Report could not be found" in response["error"] + assert "Report not found from list" in response["error"] # Tests for device endpoints @pytest.fixture()