560cbf280e
Conjunto completo de funciones SSH para operaciones remotas: conexión, verificación de host, ejecución de comandos, transferencia de archivos (upload/download) y gestión de túneles. Incluye tipo SSHConn y tests. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
61 lines
1.4 KiB
Go
61 lines
1.4 KiB
Go
package infra
|
|
|
|
import (
|
|
"os"
|
|
"path/filepath"
|
|
"strings"
|
|
"testing"
|
|
)
|
|
|
|
func TestSSHUploadDownload(t *testing.T) {
|
|
conn := skipIfNoSSH(t)
|
|
|
|
t.Run("upload y download roundtrip", func(t *testing.T) {
|
|
// Crear archivo temporal local
|
|
tmpDir := t.TempDir()
|
|
localFile := filepath.Join(tmpDir, "test_upload.txt")
|
|
content := "fn_registry ssh test: upload roundtrip"
|
|
if err := os.WriteFile(localFile, []byte(content), 0644); err != nil {
|
|
t.Fatal(err)
|
|
}
|
|
|
|
remotePath := "/tmp/fn_registry_ssh_test.txt"
|
|
|
|
// Upload
|
|
err := SSHUpload(conn, localFile, remotePath)
|
|
if err != nil {
|
|
t.Fatalf("SSHUpload: %v", err)
|
|
}
|
|
|
|
// Verificar que existe en remoto
|
|
stdout, _, code, err := SSHExec(conn, "cat "+remotePath)
|
|
if err != nil {
|
|
t.Fatalf("SSHExec cat: %v", err)
|
|
}
|
|
if code != 0 {
|
|
t.Fatalf("cat remoto fallo con code %d", code)
|
|
}
|
|
if strings.TrimSpace(stdout) != content {
|
|
t.Errorf("contenido remoto = %q, want %q", strings.TrimSpace(stdout), content)
|
|
}
|
|
|
|
// Download
|
|
downloadFile := filepath.Join(tmpDir, "test_download.txt")
|
|
err = SSHDownload(conn, remotePath, downloadFile)
|
|
if err != nil {
|
|
t.Fatalf("SSHDownload: %v", err)
|
|
}
|
|
|
|
got, err := os.ReadFile(downloadFile)
|
|
if err != nil {
|
|
t.Fatal(err)
|
|
}
|
|
if string(got) != content {
|
|
t.Errorf("downloaded = %q, want %q", string(got), content)
|
|
}
|
|
|
|
// Limpiar remoto
|
|
SSHExec(conn, "rm -f "+remotePath)
|
|
})
|
|
}
|