From 2b5d277c433c823612ceac55b5391e86fc03d7b0 Mon Sep 17 00:00:00 2001 From: belthlemar Date: Wed, 18 Oct 2023 13:58:48 +0200 Subject: [PATCH 01/10] feat(zip extractor): add support for -z option --- .../use_cases/retrieve/final_zip_extractor.py | 20 +++++++++---------- .../retriever/test_final_zip_extractor.py | 6 ++++-- 2 files changed, 14 insertions(+), 12 deletions(-) diff --git a/antareslauncher/use_cases/retrieve/final_zip_extractor.py b/antareslauncher/use_cases/retrieve/final_zip_extractor.py index 81d02cb..a9136c7 100644 --- a/antareslauncher/use_cases/retrieve/final_zip_extractor.py +++ b/antareslauncher/use_cases/retrieve/final_zip_extractor.py @@ -29,17 +29,17 @@ def extract_final_zip(self, study: StudyDTO) -> None: # If all files are in the same directory, we can extract the ZIP # file directly in the target directory. target_dir = zip_path.parent + progress_bar = self._display.generate_progress_bar( + names, desc="Extracting archive:", total=len(names) + ) + for file in progress_bar: + zf.extract(member=file, path=target_dir) else: - # Otherwise, we need to create a directory to store the results. - # This situation occurs when the ZIP file contains - # only the simulation results and not the entire study. - target_dir = zip_path.with_suffix("") - - progress_bar = self._display.generate_progress_bar( - names, desc="Extracting archive:", total=len(names) - ) - for file in progress_bar: - zf.extract(member=file, path=target_dir) + # The directory is already an output and does not need to be unzipped. + # All we have to do is rename it by removing the prefix "_finished" + # and the suffix "job_id" that lies before the ".zip". + # If these prefix/suffix prefix change, this code needs to be adapted. + zip_path.rename((zip_path.parent / (zip_path.name[9:zip_path.name.rfind("_")] + ".zip"))) except (OSError, zipfile.BadZipFile) as exc: # If we cannot extract the final ZIP file, either because the file diff --git a/tests/unit/retriever/test_final_zip_extractor.py b/tests/unit/retriever/test_final_zip_extractor.py index 7817dc0..86159a3 100644 --- a/tests/unit/retriever/test_final_zip_extractor.py +++ b/tests/unit/retriever/test_final_zip_extractor.py @@ -131,8 +131,10 @@ def test_extract_final_zip__finished_study__nominal_results(self, finished_study assert finished_study.final_zip_extracted assert not finished_study.with_error - result_dir = Path(finished_study.local_final_zipfile_path).with_suffix("") - assert result_dir.joinpath("simulation.log").is_file() + result_dir = Path(Path(finished_study.local_final_zipfile_path).parent / finished_study.name).with_suffix(".zip") + assert result_dir.exists() + with zipfile.ZipFile(result_dir, "r") as zf: + assert zf.namelist() == ["simulation.log"] @pytest.mark.unit_test def test_extract_final_zip__finished_study__reentrancy(self, finished_study: StudyDTO) -> None: From ad9bfffe62fb45664c2e3a6bec320a8ad4d813ed Mon Sep 17 00:00:00 2001 From: belthlemar Date: Wed, 18 Oct 2023 14:08:29 +0200 Subject: [PATCH 02/10] add sourecry guard close --- .../use_cases/retrieve/final_zip_extractor.py | 86 ++++++++++--------- 1 file changed, 46 insertions(+), 40 deletions(-) diff --git a/antareslauncher/use_cases/retrieve/final_zip_extractor.py b/antareslauncher/use_cases/retrieve/final_zip_extractor.py index a9136c7..143b935 100644 --- a/antareslauncher/use_cases/retrieve/final_zip_extractor.py +++ b/antareslauncher/use_cases/retrieve/final_zip_extractor.py @@ -20,43 +20,49 @@ def extract_final_zip(self, study: StudyDTO) -> None: Args: study: The current study """ - if study.finished and not study.with_error and study.local_final_zipfile_path and not study.final_zip_extracted: - zip_path = Path(study.local_final_zipfile_path) - try: - with zipfile.ZipFile(zip_path) as zf: - names = zf.namelist() - if len(names) > 1 and os.path.commonpath(names): - # If all files are in the same directory, we can extract the ZIP - # file directly in the target directory. - target_dir = zip_path.parent - progress_bar = self._display.generate_progress_bar( - names, desc="Extracting archive:", total=len(names) - ) - for file in progress_bar: - zf.extract(member=file, path=target_dir) - else: - # The directory is already an output and does not need to be unzipped. - # All we have to do is rename it by removing the prefix "_finished" - # and the suffix "job_id" that lies before the ".zip". - # If these prefix/suffix prefix change, this code needs to be adapted. - zip_path.rename((zip_path.parent / (zip_path.name[9:zip_path.name.rfind("_")] + ".zip"))) - - except (OSError, zipfile.BadZipFile) as exc: - # If we cannot extract the final ZIP file, either because the file - # doesn't exist or the ZIP file is corrupted, we find ourselves - # in a situation where the results are unusable. - # In such cases, it's best to consider the simulation as failed, - # enabling the user to restart its simulation. - study.final_zip_extracted = False - study.with_error = True - self._display.show_error( - f'"{study.name}": Final zip not extracted: {exc}', - LOG_NAME, - ) - - else: - study.final_zip_extracted = True - self._display.show_message( - f'"{study.name}": Final zip extracted', - LOG_NAME, - ) + if ( + not study.finished + or study.with_error + or not study.local_final_zipfile_path + or study.final_zip_extracted + ): + return + zip_path = Path(study.local_final_zipfile_path) + try: + with zipfile.ZipFile(zip_path) as zf: + names = zf.namelist() + if len(names) > 1 and os.path.commonpath(names): + # If all files are in the same directory, we can extract the ZIP + # file directly in the target directory. + target_dir = zip_path.parent + progress_bar = self._display.generate_progress_bar( + names, desc="Extracting archive:", total=len(names) + ) + for file in progress_bar: + zf.extract(member=file, path=target_dir) + else: + # The directory is already an output and does not need to be unzipped. + # All we have to do is rename it by removing the prefix "_finished" + # and the suffix "job_id" that lies before the ".zip". + # If these prefix/suffix prefix change, this code needs to be adapted. + zip_path.rename((zip_path.parent / (zip_path.name[9:zip_path.name.rfind("_")] + ".zip"))) + + except (OSError, zipfile.BadZipFile) as exc: + # If we cannot extract the final ZIP file, either because the file + # doesn't exist or the ZIP file is corrupted, we find ourselves + # in a situation where the results are unusable. + # In such cases, it's best to consider the simulation as failed, + # enabling the user to restart its simulation. + study.final_zip_extracted = False + study.with_error = True + self._display.show_error( + f'"{study.name}": Final zip not extracted: {exc}', + LOG_NAME, + ) + + else: + study.final_zip_extracted = True + self._display.show_message( + f'"{study.name}": Final zip extracted', + LOG_NAME, + ) From 9bcf11a2d4bd87961e74ced0468b87e4aaa31ec1 Mon Sep 17 00:00:00 2001 From: belthlemar Date: Wed, 18 Oct 2023 14:42:24 +0200 Subject: [PATCH 03/10] remove useless parenthesis --- antareslauncher/use_cases/retrieve/final_zip_extractor.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/antareslauncher/use_cases/retrieve/final_zip_extractor.py b/antareslauncher/use_cases/retrieve/final_zip_extractor.py index 143b935..6c6e28b 100644 --- a/antareslauncher/use_cases/retrieve/final_zip_extractor.py +++ b/antareslauncher/use_cases/retrieve/final_zip_extractor.py @@ -45,7 +45,7 @@ def extract_final_zip(self, study: StudyDTO) -> None: # All we have to do is rename it by removing the prefix "_finished" # and the suffix "job_id" that lies before the ".zip". # If these prefix/suffix prefix change, this code needs to be adapted. - zip_path.rename((zip_path.parent / (zip_path.name[9:zip_path.name.rfind("_")] + ".zip"))) + zip_path.rename(zip_path.parent / (zip_path.name[9:zip_path.name.rfind("_")] + ".zip")) except (OSError, zipfile.BadZipFile) as exc: # If we cannot extract the final ZIP file, either because the file From b04789a3b0f4d1fb44b68bab3f09a84f6d116d24 Mon Sep 17 00:00:00 2001 From: belthlemar Date: Wed, 18 Oct 2023 14:46:00 +0200 Subject: [PATCH 04/10] tests to see what fails on Windows --- tests/unit/retriever/test_final_zip_extractor.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/unit/retriever/test_final_zip_extractor.py b/tests/unit/retriever/test_final_zip_extractor.py index 86159a3..7f87fd2 100644 --- a/tests/unit/retriever/test_final_zip_extractor.py +++ b/tests/unit/retriever/test_final_zip_extractor.py @@ -125,8 +125,8 @@ def test_extract_final_zip__finished_study__nominal_results(self, finished_study extractor.extract_final_zip(finished_study) # Check the result - display.show_message.assert_called_once() display.show_error.assert_not_called() + display.show_message.assert_called_once() assert finished_study.final_zip_extracted assert not finished_study.with_error From e971604f730dd286dcb87b1c4b905ed0924b87b0 Mon Sep 17 00:00:00 2001 From: belthlemar Date: Wed, 18 Oct 2023 14:55:16 +0200 Subject: [PATCH 05/10] add zip.close() --- antareslauncher/use_cases/retrieve/final_zip_extractor.py | 1 + tests/unit/retriever/test_final_zip_extractor.py | 2 +- 2 files changed, 2 insertions(+), 1 deletion(-) diff --git a/antareslauncher/use_cases/retrieve/final_zip_extractor.py b/antareslauncher/use_cases/retrieve/final_zip_extractor.py index 6c6e28b..2370ece 100644 --- a/antareslauncher/use_cases/retrieve/final_zip_extractor.py +++ b/antareslauncher/use_cases/retrieve/final_zip_extractor.py @@ -46,6 +46,7 @@ def extract_final_zip(self, study: StudyDTO) -> None: # and the suffix "job_id" that lies before the ".zip". # If these prefix/suffix prefix change, this code needs to be adapted. zip_path.rename(zip_path.parent / (zip_path.name[9:zip_path.name.rfind("_")] + ".zip")) + zf.close() except (OSError, zipfile.BadZipFile) as exc: # If we cannot extract the final ZIP file, either because the file diff --git a/tests/unit/retriever/test_final_zip_extractor.py b/tests/unit/retriever/test_final_zip_extractor.py index 7f87fd2..86159a3 100644 --- a/tests/unit/retriever/test_final_zip_extractor.py +++ b/tests/unit/retriever/test_final_zip_extractor.py @@ -125,8 +125,8 @@ def test_extract_final_zip__finished_study__nominal_results(self, finished_study extractor.extract_final_zip(finished_study) # Check the result - display.show_error.assert_not_called() display.show_message.assert_called_once() + display.show_error.assert_not_called() assert finished_study.final_zip_extracted assert not finished_study.with_error From e72be67c9b43f3576089ae8355bb1eff589b4983 Mon Sep 17 00:00:00 2001 From: belthlemar Date: Wed, 18 Oct 2023 14:58:02 +0200 Subject: [PATCH 06/10] test --- antareslauncher/use_cases/retrieve/final_zip_extractor.py | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/antareslauncher/use_cases/retrieve/final_zip_extractor.py b/antareslauncher/use_cases/retrieve/final_zip_extractor.py index 2370ece..82a436b 100644 --- a/antareslauncher/use_cases/retrieve/final_zip_extractor.py +++ b/antareslauncher/use_cases/retrieve/final_zip_extractor.py @@ -40,13 +40,14 @@ def extract_final_zip(self, study: StudyDTO) -> None: ) for file in progress_bar: zf.extract(member=file, path=target_dir) + zf.close() else: + zf.close() # The directory is already an output and does not need to be unzipped. # All we have to do is rename it by removing the prefix "_finished" # and the suffix "job_id" that lies before the ".zip". # If these prefix/suffix prefix change, this code needs to be adapted. zip_path.rename(zip_path.parent / (zip_path.name[9:zip_path.name.rfind("_")] + ".zip")) - zf.close() except (OSError, zipfile.BadZipFile) as exc: # If we cannot extract the final ZIP file, either because the file From 531f77b7eb62ccb629ec289abe51701428404e29 Mon Sep 17 00:00:00 2001 From: belthlemar Date: Wed, 18 Oct 2023 15:01:22 +0200 Subject: [PATCH 07/10] remove one zf.close() --- antareslauncher/use_cases/retrieve/final_zip_extractor.py | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/antareslauncher/use_cases/retrieve/final_zip_extractor.py b/antareslauncher/use_cases/retrieve/final_zip_extractor.py index 82a436b..5e4d716 100644 --- a/antareslauncher/use_cases/retrieve/final_zip_extractor.py +++ b/antareslauncher/use_cases/retrieve/final_zip_extractor.py @@ -40,13 +40,12 @@ def extract_final_zip(self, study: StudyDTO) -> None: ) for file in progress_bar: zf.extract(member=file, path=target_dir) - zf.close() else: - zf.close() # The directory is already an output and does not need to be unzipped. # All we have to do is rename it by removing the prefix "_finished" # and the suffix "job_id" that lies before the ".zip". # If these prefix/suffix prefix change, this code needs to be adapted. + zf.close() zip_path.rename(zip_path.parent / (zip_path.name[9:zip_path.name.rfind("_")] + ".zip")) except (OSError, zipfile.BadZipFile) as exc: From 59e8e394ed2a192471f3e7d06f7ec5cf856e7a5e Mon Sep 17 00:00:00 2001 From: Laurent LAPORTE Date: Sun, 19 Nov 2023 14:39:32 +0100 Subject: [PATCH 08/10] test(zip-extractor): add unit tests with xpansion ZIP names --- .../retriever/test_final_zip_extractor.py | 30 ++++++++++++------- 1 file changed, 20 insertions(+), 10 deletions(-) diff --git a/tests/unit/retriever/test_final_zip_extractor.py b/tests/unit/retriever/test_final_zip_extractor.py index 86159a3..5357ac8 100644 --- a/tests/unit/retriever/test_final_zip_extractor.py +++ b/tests/unit/retriever/test_final_zip_extractor.py @@ -14,8 +14,12 @@ def create_final_zip(study: StudyDTO, *, scenario: str = "nominal_study") -> str """Prepare a final ZIP.""" dst_dir = Path(study.output_dir) # must exist dst_dir.mkdir(parents=True, exist_ok=True) - out_path = dst_dir.joinpath(f"finished_{study.name}_{study.job_id}.zip") - if scenario == "nominal_study": + if "xpansion" in scenario: + out_path = dst_dir.joinpath(f"finished_XPANSION_{study.name}_{study.job_id}.zip") + else: + out_path = dst_dir.joinpath(f"finished_{study.name}_{study.job_id}.zip") + if scenario in {"nominal_study", "xpansion_study"}: + # Case where the ZIP contains all the study files. with zipfile.ZipFile( out_path, mode="w", @@ -29,7 +33,8 @@ def create_final_zip(study: StudyDTO, *, scenario: str = "nominal_study") -> str f"{study.name}/output/20230922-1601eco/simulation.log", data=b"Simulation OK", ) - elif scenario == "nominal_results": + elif scenario in {"nominal_results", "xpansion_results"}: + # Case where the ZIP contains only the results. with zipfile.ZipFile( out_path, mode="w", @@ -37,8 +42,10 @@ def create_final_zip(study: StudyDTO, *, scenario: str = "nominal_study") -> str ) as zf: zf.writestr("simulation.log", data=b"Simulation OK") elif scenario == "corrupted": + # Case where the ZIP is corrupted. out_path.write_bytes(b"PK corrupted content") elif scenario == "missing": + # Case where the ZIP is missing. pass else: raise NotImplementedError(scenario) @@ -86,12 +93,13 @@ def test_extract_final_zip__finished_study__no_output(self, finished_study: Stud assert not finished_study.final_zip_extracted @pytest.mark.unit_test - def test_extract_final_zip__finished_study__nominal_study(self, finished_study: StudyDTO) -> None: + @pytest.mark.parametrize("scenario", ["nominal_study", "xpansion_study"]) + def test_extract_final_zip__finished_study__nominal_study(self, finished_study: StudyDTO, scenario: str) -> None: display = mock.Mock(spec=DisplayTerminal) display.generate_progress_bar = lambda names, *args, **kwargs: names # Prepare a valid final ZIP - finished_study.local_final_zipfile_path = create_final_zip(finished_study, scenario="nominal_study") + finished_study.local_final_zipfile_path = create_final_zip(finished_study, scenario=scenario) # Initialize and execute the ZIP extraction extractor = FinalZipExtractor(display=display) @@ -113,12 +121,13 @@ def test_extract_final_zip__finished_study__nominal_study(self, finished_study: assert result_dir.joinpath(file).is_file() @pytest.mark.unit_test - def test_extract_final_zip__finished_study__nominal_results(self, finished_study: StudyDTO) -> None: + @pytest.mark.parametrize("scenario", ["nominal_results", "xpansion_results"]) + def test_extract_final_zip__finished_study__nominal_results(self, finished_study: StudyDTO, scenario: str) -> None: display = mock.Mock(spec=DisplayTerminal) display.generate_progress_bar = lambda names, *args, **kwargs: names # Prepare a valid final ZIP - finished_study.local_final_zipfile_path = create_final_zip(finished_study, scenario="nominal_results") + finished_study.local_final_zipfile_path = create_final_zip(finished_study, scenario=scenario) # Initialize and execute the ZIP extraction extractor = FinalZipExtractor(display=display) @@ -131,18 +140,19 @@ def test_extract_final_zip__finished_study__nominal_results(self, finished_study assert finished_study.final_zip_extracted assert not finished_study.with_error - result_dir = Path(Path(finished_study.local_final_zipfile_path).parent / finished_study.name).with_suffix(".zip") + result_dir = (Path(finished_study.local_final_zipfile_path).parent / finished_study.name).with_suffix(".zip") assert result_dir.exists() with zipfile.ZipFile(result_dir, "r") as zf: assert zf.namelist() == ["simulation.log"] @pytest.mark.unit_test - def test_extract_final_zip__finished_study__reentrancy(self, finished_study: StudyDTO) -> None: + @pytest.mark.parametrize("scenario", ["nominal_study", "xpansion_study"]) + def test_extract_final_zip__finished_study__reentrancy(self, finished_study: StudyDTO, scenario: str) -> None: display = mock.Mock(spec=DisplayTerminal) display.generate_progress_bar = lambda names, *args, **kwargs: names # Prepare a valid final ZIP - finished_study.local_final_zipfile_path = create_final_zip(finished_study) + finished_study.local_final_zipfile_path = create_final_zip(finished_study, scenario=scenario) # Initialize and execute the ZIP extraction twice extractor = FinalZipExtractor(display=display) From 42dd6a456cb317d4b19ed597bbda8ab96f4eb1cb Mon Sep 17 00:00:00 2001 From: Laurent LAPORTE Date: Sun, 19 Nov 2023 14:52:21 +0100 Subject: [PATCH 09/10] fix(zip-extractor): handle ZIP files with Xpansion-style names --- .../use_cases/retrieve/final_zip_extractor.py | 38 ++++++++++--------- 1 file changed, 21 insertions(+), 17 deletions(-) diff --git a/antareslauncher/use_cases/retrieve/final_zip_extractor.py b/antareslauncher/use_cases/retrieve/final_zip_extractor.py index 5e4d716..eaf147e 100644 --- a/antareslauncher/use_cases/retrieve/final_zip_extractor.py +++ b/antareslauncher/use_cases/retrieve/final_zip_extractor.py @@ -20,33 +20,37 @@ def extract_final_zip(self, study: StudyDTO) -> None: Args: study: The current study """ - if ( - not study.finished - or study.with_error - or not study.local_final_zipfile_path - or study.final_zip_extracted - ): + if not study.finished or study.with_error or not study.local_final_zipfile_path or study.final_zip_extracted: return zip_path = Path(study.local_final_zipfile_path) try: + # First, we detect the ZIP layout by looking at the names of the files it contains. with zipfile.ZipFile(zip_path) as zf: names = zf.namelist() - if len(names) > 1 and os.path.commonpath(names): - # If all files are in the same directory, we can extract the ZIP - # file directly in the target directory. + file_count = len(names) + has_unique_folder = file_count > 1 and os.path.commonpath(names) + + if has_unique_folder: + # If the ZIP file contains a unique folder, it contains the whole study. + # We can extract it directly in the target directory. + with zipfile.ZipFile(zip_path) as zf: target_dir = zip_path.parent progress_bar = self._display.generate_progress_bar( - names, desc="Extracting archive:", total=len(names) + names, desc="Extracting archive:", total=file_count ) for file in progress_bar: zf.extract(member=file, path=target_dir) - else: - # The directory is already an output and does not need to be unzipped. - # All we have to do is rename it by removing the prefix "_finished" - # and the suffix "job_id" that lies before the ".zip". - # If these prefix/suffix prefix change, this code needs to be adapted. - zf.close() - zip_path.rename(zip_path.parent / (zip_path.name[9:zip_path.name.rfind("_")] + ".zip")) + + else: + # The directory is already an output and does not need to be unzipped. + # All we have to do is rename it by removing the prefix "finished_" + # and the suffix "_{job_id}" that lies before the ".zip". + # e.g.: "finished_Foo-Study_123456.zip" -> "Foo-Study.zip". + # or: "finished_XPANSION_Foo-Study_123456.zip" -> "Foo-Study_123456.zip". + new_name = zip_path.name.lstrip("finished_") + new_name = new_name.lstrip("XPANSION_") + new_name = new_name.split("_", 1)[0] + ".zip" + zip_path.rename(zip_path.parent / new_name) except (OSError, zipfile.BadZipFile) as exc: # If we cannot extract the final ZIP file, either because the file From 627e3d911fb801ba3eee5cfd09d8f372d8d5ea2e Mon Sep 17 00:00:00 2001 From: Laurent LAPORTE Date: Sun, 19 Nov 2023 15:02:41 +0100 Subject: [PATCH 10/10] refactor(ssh-connection): sort imports and factorize common error messages --- .../remote_environnement/ssh_connection.py | 42 +++++++++++-------- 1 file changed, 24 insertions(+), 18 deletions(-) diff --git a/antareslauncher/remote_environnement/ssh_connection.py b/antareslauncher/remote_environnement/ssh_connection.py index 7b2e3ff..76b0207 100644 --- a/antareslauncher/remote_environnement/ssh_connection.py +++ b/antareslauncher/remote_environnement/ssh_connection.py @@ -5,14 +5,20 @@ import stat import textwrap import time -from pathlib import Path, PurePosixPath import typing as t +from pathlib import Path, PurePosixPath import paramiko RemotePath = PurePosixPath LocalPath = Path +PARAMIKO_SSH_ERROR = "Paramiko SSH Exception" +REMOTE_CONNECTION_ERROR = "Failed to connect to remote host" +IO_ERROR = "IO Error" +FILE_NOT_FOUND_ERROR = "File not found error" +DIRECTORY_NOT_FOUND_ERROR = "Directory not found error" + class SshConnectionError(Exception): """ @@ -264,7 +270,7 @@ def execute_command(self, command: str): with self.ssh_client() as client: # fmt: off self.logger.info(f"Running SSH command [{command}]...") - stdin, stdout, stderr = client.exec_command(command, timeout=30) + _, stdout, stderr = client.exec_command(command, timeout=30) output = stdout.read().decode("utf-8").strip() error = stderr.read().decode("utf-8").strip() self.logger.info(f"SSH command stdout:\n{textwrap.indent(output, 'SSH OUTPUT> ')}") @@ -301,13 +307,13 @@ def upload_file(self, src: str, dst: str): sftp_client.put(src, dst) sftp_client.close() except paramiko.SSHException: - self.logger.debug("Paramiko SSH Exception", exc_info=True) + self.logger.debug(PARAMIKO_SSH_ERROR, exc_info=True) result_flag = False except IOError: - self.logger.debug("IO Error", exc_info=True) + self.logger.debug(IO_ERROR, exc_info=True) result_flag = False except ConnectionFailedException: - self.logger.error("Failed to connect to remote host", exc_info=True) + self.logger.error(REMOTE_CONNECTION_ERROR, exc_info=True) result_flag = False return result_flag @@ -330,10 +336,10 @@ def download_file(self, src: str, dst: str): sftp_client.close() result_flag = True except paramiko.SSHException: - self.logger.error("Paramiko SSH Exception", exc_info=True) + self.logger.error(PARAMIKO_SSH_ERROR, exc_info=True) result_flag = False except ConnectionFailedException: - self.logger.error("Failed to connect to remote host", exc_info=True) + self.logger.error(REMOTE_CONNECTION_ERROR, exc_info=True) result_flag = False return result_flag @@ -370,10 +376,10 @@ def download_files( self.logger.error(f"Timeout: {exc}", exc_info=True) return [] except paramiko.SSHException: - self.logger.error("Paramiko SSH Exception", exc_info=True) + self.logger.error(PARAMIKO_SSH_ERROR, exc_info=True) return [] except ConnectionFailedException: - self.logger.error("Failed to connect to remote host", exc_info=True) + self.logger.error(REMOTE_CONNECTION_ERROR, exc_info=True) return [] def _download_files( @@ -449,10 +455,10 @@ def check_remote_dir_exists(self, dir_path): else: raise IOError except FileNotFoundError: - self.logger.debug("FileNotFoundError", exc_info=True) + self.logger.debug(FILE_NOT_FOUND_ERROR, exc_info=True) result_flag = False except ConnectionFailedException: - self.logger.error("Failed to connect to remote host", exc_info=True) + self.logger.error(REMOTE_CONNECTION_ERROR, exc_info=True) result_flag = False return result_flag @@ -480,10 +486,10 @@ def check_file_not_empty(self, file_path): else: raise IOError(f"Not a regular file: '{file_path}'") except FileNotFoundError: - self.logger.debug("FileNotFoundError", exc_info=True) + self.logger.debug(FILE_NOT_FOUND_ERROR, exc_info=True) result_flag = False except ConnectionFailedException: - self.logger.error("Failed to connect to remote host", exc_info=True) + self.logger.error(REMOTE_CONNECTION_ERROR, exc_info=True) result_flag = False return result_flag @@ -516,7 +522,7 @@ def make_dir(self, dir_path): self.logger.debug("Paramiko SSHException", exc_info=True) result_flag = False except ConnectionFailedException: - self.logger.error("Failed to connect to remote host", exc_info=True) + self.logger.error(REMOTE_CONNECTION_ERROR, exc_info=True) result_flag = False return result_flag @@ -549,7 +555,7 @@ def remove_file(self, file_path): finally: sftp_client.close() except ConnectionFailedException: - self.logger.error("Failed to connect to remote host", exc_info=True) + self.logger.error(REMOTE_CONNECTION_ERROR, exc_info=True) result_flag = False return result_flag @@ -577,12 +583,12 @@ def remove_dir(self, dir_path): sftp_client.rmdir(dir_path) result_flag = True except FileNotFoundError: - self.logger.debug("DirNotFound nothing to remove", exc_info=True) + self.logger.debug(DIRECTORY_NOT_FOUND_ERROR, exc_info=True) result_flag = True finally: sftp_client.close() except ConnectionFailedException: - self.logger.error("Failed to connect to remote host", exc_info=True) + self.logger.error(REMOTE_CONNECTION_ERROR, exc_info=True) result_flag = False return result_flag @@ -591,5 +597,5 @@ def test_connection(self): with self.ssh_client(): return True except ConnectionFailedException: - self.logger.error("Failed to connect to remote host", exc_info=True) + self.logger.error(REMOTE_CONNECTION_ERROR, exc_info=True) return False