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>
This commit is contained in:
95
tests/test_ssh_target_tracking.py
Normal file
95
tests/test_ssh_target_tracking.py
Normal file
@@ -0,0 +1,95 @@
|
||||
"""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")
|
||||
Reference in New Issue
Block a user