Files
pyssh-client/tests/test_ssh_target_tracking.py
Florian aa890c5847
Some checks failed
CI / lint (push) Has been cancelled
CI / tests (push) Has been cancelled
CI / typecheck (push) Has been cancelled
CI / build (push) Has been cancelled
SFTP sur cette connexion : ne plus perdre la cible ssh detectee
Signale par l'utilisateur avec une capture d'ecran : bouton "SFTP sur cette
connexion" clique depuis un terminal local visiblement connecte en ssh
(prompt root@debian:~#), formulaire de connexion vide a l'arrivee - "si je
dois remplir le formulaire pour une session actuelle ca perd tout son sens".

Cause reelle : detect_ssh_target() ne scrutait le texte du terminal qu'au
moment du clic (buffer visible + historique pyte, 5000 lignes). Si la ligne
`ssh user@hote` tapee par l'utilisateur n'y figure plus au moment du clic
(beaucoup de sortie depuis, ecran efface...), plus rien n'est detectable -
alors meme que la connexion ssh est toujours active. La capture montree
correspond exactement a ce cas : un ecran efface apres la connexion.

Corrige a la racine plutot qu'en agrandissant simplement l'historique
scrute : app/ui/tabs.py (BaseTerminalTab) memorise desormais la cible des
qu'une commande ssh apparait dans la sortie recue (_track_ssh_target,
cablee comme terminal.feed sur data_received), et ne l'oublie plus jamais -
detect_current_ssh_target() la renvoie en priorite, avec un dernier examen du
buffer actuel seulement en repli. Le bouton "SFTP sur cette connexion" et le
raccourci global Ctrl+Shift+F (ConnectionController._current_tab_ssh_target)
utilisent tous les deux ce nouveau point d'entree unique.

tests/test_ssh_target_tracking.py (4 verifications, nouveau fichier - ce
bouton n'avait encore aucun test dedie) : memorisation a la frappe, cible
toujours renvoyee meme quand le buffer live ne la contient plus, mise a jour
vers une commande ssh plus recente, bouton emettant bien la cible memorisee.
Suite complete revalidee (36/36), ruff propre.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
2026-09-05 09:11:35 +02:00

96 lines
3.9 KiB
Python

"""Detection de la cible ssh "en cours" dans un terminal local : signale par
l'utilisateur (bouton "SFTP sur cette connexion" revenant a un formulaire
vide alors qu'une session ssh etait bien active a l'ecran).
Cause reelle : detect_ssh_target() ne scrutait le texte du terminal qu'au
moment du clic, en repartant du buffer/historique ACTUEL - si la ligne
`ssh user@hote` tapee par l'utilisateur en etait sortie entre-temps (beaucoup
de sortie, ecran efface...), plus rien n'etait detectable, meme si la
connexion ssh etait toujours active. Corrige en memorisant la cible des
qu'elle apparait dans la sortie (BaseTerminalTab._track_ssh_target), pour ne
plus dependre de ce qui est encore present dans le buffer au moment du clic.
Important : on alimente le terminal via connection.data_received.emit(...),
pas terminal.feed(...) directement - _track_ssh_target est cablee sur ce
signal (comme terminal.feed lui-meme), l'appeler directement contournerait le
suivi et ne testerait que le repli (deja fonctionnel avant ce correctif)."""
import pathlib
import sys
sys.path.insert(0, str(pathlib.Path(__file__).resolve().parent.parent))
from unittest.mock import patch
from PySide6.QtWidgets import QApplication
from app.local_terminal import LocalTerminalConnection
from app.ui.tabs import LocalTerminalTabWidget
app = QApplication.instance() or QApplication(sys.argv)
def make_tab():
return LocalTerminalTabWidget()
def feed(tab, data: bytes) -> None:
tab.connection.data_received.emit(data)
print("=== 1. Une commande ssh tapee est memorisee des qu'elle apparait a l'ecran ===")
with patch.object(LocalTerminalConnection, "start", lambda self: None):
tab = make_tab()
assert tab.detect_current_ssh_target() is None
feed(tab, b"user@PC MINGW64 ~\r\n$ ssh root@debian\r\n")
target = tab.detect_current_ssh_target()
print(" cible detectee:", target)
assert target == {"user": "root", "host": "debian", "port": 22}
tab.close_connection()
print(" OK")
print()
print("=== 2. La cible reste memorisee meme si la commande disparait du buffer ensuite ===")
with patch.object(LocalTerminalConnection, "start", lambda self: None):
tab = make_tab()
feed(tab, b"$ ssh root@debian\r\n")
assert tab._last_ssh_target == {"user": "root", "host": "debian", "port": 22}
# simule la perte de la ligne d'origine (beaucoup de sortie, ecran efface...) :
# buffer_text() ne renvoie plus rien d'exploitable, mais la cible reste connue
with patch.object(type(tab.terminal), "buffer_text", return_value="root@debian:~# "):
target = tab.detect_current_ssh_target()
print(" cible apres 'perte' du buffer:", target)
assert target == {"user": "root", "host": "debian", "port": 22}
tab.close_connection()
print(" OK")
print()
print("=== 3. Une nouvelle commande ssh remplace bien l'ancienne cible memorisee ===")
with patch.object(LocalTerminalConnection, "start", lambda self: None):
tab = make_tab()
feed(tab, b"$ ssh root@debian\r\n")
assert tab._last_ssh_target["host"] == "debian"
feed(tab, b"logout\r\n$ ssh admin@192.168.1.50\r\n")
target = tab.detect_current_ssh_target()
print(" nouvelle cible:", target)
assert target == {"user": "admin", "host": "192.168.1.50", "port": 22}
tab.close_connection()
print(" OK")
print()
print("=== 4. Bouton 'SFTP sur cette connexion' : emet la cible memorisee, pas un formulaire vide ===")
with patch.object(LocalTerminalConnection, "start", lambda self: None):
tab = make_tab()
feed(tab, b"$ ssh root@debian\r\n")
with patch.object(type(tab.terminal), "buffer_text", return_value="root@debian:~# "):
received = []
tab.sftp_requested.connect(lambda t: received.append(t))
tab.sftp_btn.click()
print(" emis par le bouton:", received)
assert received == [{"user": "root", "host": "debian", "port": 22}]
tab.close_connection()
print(" OK")
print()
print("SSH TARGET TRACKING : TOUS LES TESTS OK")