feat: funciones SSH para infra — conn, check, exec, download, upload, tunnel
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>
This commit is contained in:
@@ -0,0 +1,73 @@
|
||||
package infra
|
||||
|
||||
import (
|
||||
"testing"
|
||||
)
|
||||
|
||||
func TestSSHConnDestination(t *testing.T) {
|
||||
tests := []struct {
|
||||
name string
|
||||
conn SSHConn
|
||||
want string
|
||||
}{
|
||||
{"con user", SSHConn{Host: "example.com", User: "deploy"}, "deploy@example.com"},
|
||||
{"sin user", SSHConn{Host: "example.com"}, "example.com"},
|
||||
{"con IP", SSHConn{Host: "10.0.0.1", User: "root"}, "root@10.0.0.1"},
|
||||
}
|
||||
for _, tt := range tests {
|
||||
t.Run(tt.name, func(t *testing.T) {
|
||||
got := tt.conn.destination()
|
||||
if got != tt.want {
|
||||
t.Errorf("destination() = %q, want %q", got, tt.want)
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
func TestSSHConnSSHArgs(t *testing.T) {
|
||||
t.Run("puerto default", func(t *testing.T) {
|
||||
conn := SSHConn{Host: "example.com", User: "deploy"}
|
||||
args := conn.sshArgs()
|
||||
assertContains(t, args, "-p", "22")
|
||||
})
|
||||
|
||||
t.Run("puerto custom", func(t *testing.T) {
|
||||
conn := SSHConn{Host: "example.com", Port: 2222}
|
||||
args := conn.sshArgs()
|
||||
assertContains(t, args, "-p", "2222")
|
||||
})
|
||||
|
||||
t.Run("con key path", func(t *testing.T) {
|
||||
conn := SSHConn{Host: "example.com", KeyPath: "/home/user/.ssh/id_ed25519"}
|
||||
args := conn.sshArgs()
|
||||
assertContains(t, args, "-i", "/home/user/.ssh/id_ed25519")
|
||||
})
|
||||
|
||||
t.Run("sin key path no incluye -i", func(t *testing.T) {
|
||||
conn := SSHConn{Host: "example.com"}
|
||||
args := conn.sshArgs()
|
||||
for _, a := range args {
|
||||
if a == "-i" {
|
||||
t.Error("sshArgs() no debe incluir -i si KeyPath esta vacio")
|
||||
}
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
func TestSSHConnSCPArgs(t *testing.T) {
|
||||
t.Run("usa -P mayuscula para puerto", func(t *testing.T) {
|
||||
conn := SSHConn{Host: "example.com", Port: 2222}
|
||||
args := conn.scpArgs()
|
||||
assertContains(t, args, "-P", "2222")
|
||||
})
|
||||
}
|
||||
|
||||
func assertContains(t *testing.T, args []string, flag, value string) {
|
||||
t.Helper()
|
||||
for i, a := range args {
|
||||
if a == flag && i+1 < len(args) && args[i+1] == value {
|
||||
return
|
||||
}
|
||||
}
|
||||
t.Errorf("args %v no contiene %s %s", args, flag, value)
|
||||
}
|
||||
Reference in New Issue
Block a user