Files
llmgw/internal/join/join_test.go
T
Ilker ManapandClaude Opus 5.5 f5c79052b1 Let a machine join a setup by code, dialling out, with nothing logging in
The setup screens can reach a database machine by a join code instead of
ssh: they listen on 7444 and show a short code; llmgw join dials out,
checks the setup by fingerprint, admits itself with the code's secret, and
runs what the setup sends until it is done. A joined machine is one more
onboard.Remote, so checks and the Patroni install run over it unchanged.

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
2026-10-03 21:49:15 +02:00

95 lines
2.9 KiB
Go

package join
import (
"context"
"strings"
"testing"
"time"
)
func listen(t *testing.T) *Listener {
t.Helper()
l, err := Listen("127.0.0.1:0", "", time.Hour)
if err != nil {
t.Fatal(err)
}
l.addr = l.ln.Addr().String()
t.Cleanup(func() { _ = l.Close() })
return l
}
func TestAJoinedMachineRunsWhatTheSetupSendsUntilItIsDone(t *testing.T) {
l := listen(t)
code, arrived := l.Code("database")
parsed, err := Parse(code.String())
if err != nil || parsed.Role != "database" {
t.Fatalf("%v %+v", err, parsed)
}
var said []string
served := make(chan error, 1)
go func() { served <- Serve(context.Background(), parsed, func(s string) { said = append(said, s) }) }()
var m *Remote
select {
case m = <-arrived:
case err := <-served:
t.Fatalf("join ended before arriving: %v", err)
case <-time.After(5 * time.Second):
t.Fatal("the machine never arrived")
}
if m.Hostname == "" || m.Addr != "127.0.0.1" {
t.Errorf("arrived as %q from %q", m.Hostname, m.Addr)
}
out, err := m.Run(context.Background(), "set -e\ntr a-z A-Z", []byte("hello\n"))
if err != nil || string(out) != "HELLO\n" {
t.Fatalf("%q, %v", out, err)
}
if out, err := m.Run(context.Background(), "echo nope >&2; exit 3", nil); err == nil || !strings.Contains(string(out), "nope") {
t.Errorf("a failing script: %q, %v", out, err)
}
_ = m.Close()
if err := <-served; err != nil {
t.Errorf("join did not end cleanly when the setup was done: %v", err)
}
if len(said) < 2 || !strings.Contains(strings.Join(said, "\n"), "tr a-z A-Z") {
t.Errorf("the machine's operator was not told what ran: %q", said)
}
// The code was for one machine.
if err := Serve(context.Background(), parsed, func(string) {}); err == nil || !strings.Contains(err.Error(), "used already") {
t.Errorf("a code used twice: %v", err)
}
}
func TestAJoinRefusesAListenerThatIsNotTheOneInTheCode(t *testing.T) {
l := listen(t)
code, _ := l.Code("node")
other := listen(t)
code.Addr = other.addr // what the code names is elsewhere
err := Serve(context.Background(), code, func(string) {})
if err == nil || !strings.Contains(err.Error(), "not the setup") {
t.Errorf("joined a stranger: %v", err)
}
}
func TestAnExpiredOrDamagedCodeIsRefusedBeforeDialling(t *testing.T) {
c := Code{Addr: "10.0.0.5:7444", Role: "node", Expires: time.Now().Add(-time.Minute).Unix()}
if _, err := Parse(c.String()); err == nil || !strings.Contains(err.Error(), "expired") {
t.Errorf("expired: %v", err)
}
if _, err := Parse(c.String()[:30]); err == nil {
t.Error("a truncated code was read")
}
if _, err := Parse("ssh-rsa AAAA"); err == nil {
t.Error("something else was read as a code")
}
// Short enough to copy from a screen in one line.
c.Expires = time.Now().Add(time.Hour).Unix()
if n := len(c.String()); n > 100 {
t.Errorf("a code is %d characters", n)
}
if back, err := Parse(c.String()); err != nil || back.Addr != c.Addr || back.Role != "node" {
t.Errorf("%+v, %v", back, err)
}
}