From fe37cf366018fa127a520d124ddbfed576016cd6 Mon Sep 17 00:00:00 2001 From: Raykov-MS Date: Wed, 29 Jul 2026 12:04:26 +0300 Subject: [PATCH] Revert diagntostics changes --- app/pipeline/file_manager.py | 24 ++++++++++++++--------- app/samba_access.py | 34 +++++++++++++-------------------- tests/unit/test_file_manager.py | 28 +++++++++++++++++++++++++++ tests/unit/test_samba_access.py | 15 --------------- 4 files changed, 56 insertions(+), 45 deletions(-) delete mode 100644 tests/unit/test_samba_access.py diff --git a/app/pipeline/file_manager.py b/app/pipeline/file_manager.py index 82dc3eb..b622c9d 100644 --- a/app/pipeline/file_manager.py +++ b/app/pipeline/file_manager.py @@ -54,7 +54,7 @@ class SMBClientConnection: self.smb_base_path = _normalize_unc_path(smb_base_path) self.user_name = str((user_params or {}).get("user_name") or "") self.password = str((user_params or {}).get("password") or "") - self._registered = False + self._registered_servers: set[str] = set() def __enter__(self) -> SMBClientConnection: self._ensure_registered() @@ -171,28 +171,34 @@ class SMBClientConnection: return smbclient.open_file(full_path, mode=mode) def _ensure_registered(self) -> None: - if self._registered: + self._ensure_registered_for_server(_extract_server(self.smb_base_path)) + + def _ensure_registered_for_server(self, server: str) -> None: + normalized_server = server.lower().strip() + if normalized_server in self._registered_servers: return if not self.user_name: raise RuntimeError("Введите логин SAMBA.") smbclient = _import_smbclient() - server = _extract_server(self.smb_base_path) try: smbclient.register_session( - server=server, + server=normalized_server, username=self.user_name, password=self.password, ) except Exception as exc: # noqa: BLE001 raise RuntimeError(f"Ошибка подключения к SMB: {exc}") from exc - self._registered = True + self._registered_servers.add(normalized_server) def _resolve_path(self, path: str) -> str: if path.startswith("//") or path.startswith("\\\\"): - return _normalize_unc_path(path) - if _looks_like_unc_without_prefix(path, self.smb_base_path): - return _normalize_unc_path("//" + path.lstrip("/\\")) - return _normalize_unc_path(join_path(self.smb_base_path, path)) + full_path = _normalize_unc_path(path) + elif _looks_like_unc_without_prefix(path, self.smb_base_path): + full_path = _normalize_unc_path("//" + path.lstrip("/\\")) + else: + full_path = _normalize_unc_path(join_path(self.smb_base_path, path)) + self._ensure_registered_for_server(_extract_server(full_path)) + return full_path def connect_samba( diff --git a/app/samba_access.py b/app/samba_access.py index 00445da..9ef5294 100644 --- a/app/samba_access.py +++ b/app/samba_access.py @@ -31,19 +31,22 @@ def check_access_and_list_files( except RuntimeError as exc: return False, _format_connect_error(str(exc)), [] + # Early handshake to surface auth/network errors clearly. + try: + with samba_conn: + pass + except Exception as exc: # noqa: BLE001 + return False, _format_connect_error(str(exc)), [] + try: ensure_dir_exists(input_dir, samba_conn=samba_conn) except Exception as exc: # noqa: BLE001 - return ( - False, - (f"Ошибка этапа создания входной папки Input: {input_dir}. {exc}"), - [], - ) + return False, f"Не удалось создать входную папку: {input_dir}. {exc}", [] if not samba_conn.path_exists(input_dir): return ( False, ( - "Ошибка этапа создания входной папки Input: " + "Не удалось создать входную папку: " f"{input_dir}. Проверьте права на родительский каталог." ), [], @@ -51,14 +54,7 @@ def check_access_and_list_files( ok, error = check_input_dir_access(Path(input_dir), samba_conn=samba_conn) if not ok: - return ( - False, - ( - "Ошибка этапа проверки доступа к папке Input: " - f"{error or 'нет прав на чтение/листинг.'}" - ), - [], - ) + return False, error or "Ошибка доступа к входной папке.", [] try: with samba_conn: @@ -69,11 +65,7 @@ def check_access_and_list_files( if samba_conn.is_file(full_path): files.append(name) except Exception as exc: # noqa: BLE001 - return ( - False, - (f"Ошибка этапа чтения содержимого папки Input: {input_dir}. {exc}"), - [], - ) + return False, f"Ошибка чтения содержимого входной папки: {input_dir}. {exc}", [] return True, "", files @@ -87,5 +79,5 @@ def _format_connect_error(details: str) -> str: "no username or password", ) if any(hint in normalized for hint in auth_hints): - return f"Ошибка этапа подключения к SMB (аутентификация). {details}" - return f"Ошибка этапа подключения к SMB. {details}" + return f"Ошибка аутентификации SMB. {details}" + return f"Ошибка подключения к SMB. {details}" diff --git a/tests/unit/test_file_manager.py b/tests/unit/test_file_manager.py index b3408fa..2217099 100644 --- a/tests/unit/test_file_manager.py +++ b/tests/unit/test_file_manager.py @@ -4,6 +4,7 @@ import shutil from pathlib import Path from app.pipeline.file_manager import ( + SMBClientConnection, check_dir_write_access, create_run_context, move_file_to_error, @@ -179,3 +180,30 @@ def test_check_dir_write_access_fails_without_open_or_upload(tmp_path: Path) -> assert ok is False assert error is not None + + +def test_smb_connection_registers_sessions_for_multiple_servers(monkeypatch) -> None: + class FakeSmbClient: + def __init__(self) -> None: + self.registered: list[str] = [] + + def register_session(self, server: str, username: str, password: str) -> None: + _ = username, password + self.registered.append(server) + + def stat(self, _path: str) -> None: + return None + + fake = FakeSmbClient() + monkeypatch.setattr("app.pipeline.file_manager._import_smbclient", lambda: fake) + + conn = SMBClientConnection( + smb_base_path="//sgo-fc01-r06/sfm/ОТЧЕТ_7081У", + user_params={"user_name": "user", "password": "pass"}, + ) + with conn: + pass + conn.path_exists("//sgo-fc01-r13/inbox-intech/Exchange/Raykov/Input") + + assert "sgo-fc01-r06" in fake.registered + assert "sgo-fc01-r13" in fake.registered diff --git a/tests/unit/test_samba_access.py b/tests/unit/test_samba_access.py deleted file mode 100644 index 902a7f5..0000000 --- a/tests/unit/test_samba_access.py +++ /dev/null @@ -1,15 +0,0 @@ -from __future__ import annotations - -from app.samba_access import _format_connect_error - - -def test_format_connect_error_marks_authentication_stage() -> None: - message = _format_connect_error("Ошибка подключения к SMB: STATUS_LOGON_FAILURE") - assert "аутентификация" in message.lower() - assert "STATUS_LOGON_FAILURE" in message - - -def test_format_connect_error_marks_generic_connect_stage() -> None: - message = _format_connect_error("Ошибка подключения к SMB: timed out") - assert message.startswith("Ошибка этапа подключения к SMB.") - assert "аутентификация" not in message.lower()