package infra import ( "fmt" "net" "testing" "time" ) func TestSSHTunnelOpenClose(t *testing.T) { conn := skipIfNoSSH(t) t.Run("abre tunel y lo cierra", func(t *testing.T) { // Usar puerto alto aleatorio para evitar conflictos localPort := 19876 // Tunel a localhost:22 del remoto (el propio sshd) pid, err := SSHTunnelOpen(conn, localPort, "localhost", 22) if err != nil { t.Fatalf("SSHTunnelOpen: %v", err) } if pid <= 0 { t.Fatalf("PID invalido: %d", pid) } // Verificar que el puerto local esta escuchando time.Sleep(300 * time.Millisecond) c, err := net.DialTimeout("tcp", fmt.Sprintf("localhost:%d", localPort), 2*time.Second) if err != nil { // Limpiar antes de fallar SSHTunnelClose(pid) t.Fatalf("no se puede conectar al tunel en localhost:%d: %v", localPort, err) } c.Close() // Cerrar tunel err = SSHTunnelClose(pid) if err != nil { t.Errorf("SSHTunnelClose: %v", err) } // Verificar que el puerto ya no escucha time.Sleep(300 * time.Millisecond) c, err = net.DialTimeout("tcp", fmt.Sprintf("localhost:%d", localPort), 1*time.Second) if err == nil { c.Close() t.Error("el tunel sigue abierto despues de SSHTunnelClose") } }) }