Skip to content

Fix SFTP path checks hiding a failed reconnect, restore the SFTP tests - #175

Merged
penguinolog merged 3 commits into
masterfrom
fix-sftp-check-hides-reconnect-failure
Oct 29, 2026
Merged

penguinolog merged 3 commits into
masterfrom
fix-sftp-check-hides-reconnect-failure

Conversation

@penguinolog

Copy link
Copy Markdown
Collaborator

Follow-up to 8.2.1: the path checks reported a failed reconnect as a missing path, and the restored SFTP tests found a defect in upload().

  • exists, isfile, isdir and islink opened the SFTP session inside the try that maps OSError to False.
    Since 8.2.1 a closed client reconnects there, so a refused or unreachable host was reported as "path does not exist" and callers silently skipped work.
    The session is now opened before the try; only an error from lstat becomes False.
  • upload() of a directory never created the remote directory it copies into (regression from the move to pathlib).
    A new target was created only as a side effect of mkdir -p for a subdirectory, so the upload failed when a file came first, and an empty directory produced nothing.
  • The five skipped SFTP tests (mkdir, rm_rf, upload_file, upload_dir, download) are ported to pytest on the shared fixtures, with a temporary local tree instead of os.path/os.walk mocks. No test is skipped any more.

Behaviour change: a path check on a client whose reconnect fails now raises instead of returning False; documented as versionchanged:: 8.2.2.

mkdir, rm_rf, upload and download were tested only by skipped tests whose
mocks no longer matched the code (os.path and os.walk instead of pathlib).

- Rewrite them as pytest functions on the shared conftest fixtures.
- Use a temporary local tree instead of mocking the local filesystem.
- Cover upload into a remote directory and download of a missing path and
  of a directory.
Since 8.2.1 a closed client reconnects before opening SFTP, but exists,
isfile, isdir and islink did that inside the try that maps OSError to
False. A reconnect that failed with a socket error (connection refused,
host unreachable) was therefore reported as a missing path, and a caller
skipped a cleanup or an upload without any error.

- Open the session before the try, so only an error from lstat becomes False.
- Document the raised exceptions in the docstrings and in SSHClient.rst.
upload() copied the contents of a local directory but never created the
remote directory they go into. A target that did not exist yet was
created only as a side effect of mkdir -p for a subdirectory, so the
upload failed when a file came first, and an empty directory produced
nothing.

- Create the target directory before copying what is inside the source.
- Test upload into an existing remote directory and to a new path.
@penguinolog
penguinolog requested a review from dis-xcom as a code owner October 29, 2026 17:43
@coveralls

Copy link
Copy Markdown
Collaborator

Coverage Report for CI Build 40923968677

Coverage increased (+2.2%) to 88.564%

Details

  • Coverage increased (+2.2%) from the base build.
  • Patch coverage: 9 of 9 lines across 2 files are fully covered (100%).
  • No coverage regressions found.

Uncovered Changes

No uncovered changes found.

Coverage Regressions

No coverage regressions found.


Coverage Stats

Coverage Status
Relevant Lines: 1919
Covered Lines: 1747
Line Coverage: 91.04%
Relevant Branches: 442
Covered Branches: 344
Branch Coverage: 77.83%
Branches in Coverage %: Yes
Coverage Strength: 6.95 hits per line

💛 - Coveralls

@penguinolog
penguinolog merged commit fe05177 into master Oct 29, 2026
37 checks passed
@penguinolog
penguinolog deleted the fix-sftp-check-hides-reconnect-failure branch October 29, 2026 17:48
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants