package actuator import ( "bytes" "context" "crypto/ed25519" "crypto/rand" "encoding/pem" "os" "path/filepath" "strings" "testing" "golang.org/x/crypto/ssh" ) func TestLoadSignerRejectsBadInput(t *testing.T) { if _, err := LoadSignerFromBytes([]byte("not a private key")); err == nil { t.Error("LoadSignerFromBytes should reject a non-key input") } if _, err := LoadSigner("/nonexistent/key"); err == nil { t.Error("LoadSigner should fail on a missing file") } } func TestLoadSignerRoundTrip(t *testing.T) { _, priv, err := ed25519.GenerateKey(rand.Reader) if err != nil { t.Fatalf("generate key: %v", err) } block, err := ssh.MarshalPrivateKey(priv, "") if err != nil { t.Fatalf("marshal private key: %v", err) } pemBytes := pem.EncodeToMemory(block) signer, err := LoadSignerFromBytes(pemBytes) if err != nil { t.Fatalf("LoadSignerFromBytes on a valid key: %v", err) } if signer == nil { t.Fatal("signer is nil") } dir := t.TempDir() path := filepath.Join(dir, "id_ed25519") if err := os.WriteFile(path, pemBytes, 0o600); err != nil { t.Fatalf("write key file: %v", err) } fromFile, err := LoadSigner(path) if err != nil { t.Fatalf("LoadSigner(%s): %v", path, err) } if !bytes.Equal(fromFile.PublicKey().Marshal(), signer.PublicKey().Marshal()) { t.Error("file and in-memory signers resolved to different public keys") } } // Dial needs a real SSH server to run a command, but its option normalization // is verifiable without one: a zero Port must default to 22 (so the dial error // references host:22, not host:0), and a closed port yields a dial error rather // than panicking. func TestDialDefaultsPort(t *testing.T) { _, err := Dial(context.Background(), DialOptions{Host: "127.0.0.1", Signer: mustSigner(t)}) if err == nil { t.Fatal("Dial to a closed port should fail") } if !strings.Contains(err.Error(), "127.0.0.1:22") { t.Errorf("Dial error = %q, want it to reference 127.0.0.1:22", err) } } func mustSigner(t *testing.T) ssh.Signer { t.Helper() _, priv, err := ed25519.GenerateKey(rand.Reader) if err != nil { t.Fatalf("generate key: %v", err) } block, err := ssh.MarshalPrivateKey(priv, "") if err != nil { t.Fatalf("marshal key: %v", err) } s, err := LoadSignerFromBytes(pem.EncodeToMemory(block)) if err != nil { t.Fatalf("parse key: %v", err) } return s }