diff options
| author | Elizabeth Alexander Hunt <me@liz.coffee> | 2026-06-20 09:40:07 -0700 |
|---|---|---|
| committer | Elizabeth Alexander Hunt <me@liz.coffee> | 2026-06-20 09:40:07 -0700 |
| commit | fb653292612eddca5b088ed88466c546d1597107 (patch) | |
| tree | 900ed32e066812688858ed3bb15128c41bb78054 /adapters/rcon/rcon_test.go | |
| download | penguins.lan-fb653292612eddca5b088ed88466c546d1597107.tar.gz penguins.lan-fb653292612eddca5b088ed88466c546d1597107.zip | |
Initial commit
Diffstat (limited to 'adapters/rcon/rcon_test.go')
| -rw-r--r-- | adapters/rcon/rcon_test.go | 91 |
1 files changed, 91 insertions, 0 deletions
diff --git a/adapters/rcon/rcon_test.go b/adapters/rcon/rcon_test.go new file mode 100644 index 0000000..f712fa5 --- /dev/null +++ b/adapters/rcon/rcon_test.go @@ -0,0 +1,91 @@ +package rcon + +import ( + "encoding/binary" + "errors" + "io" + "net" + "testing" + "time" +) + +func writeTestPacket(w io.Writer, id, typ int32, body string) { + binary.Write(w, binary.LittleEndian, int32(headerSize+len(body)+paddingSize)) + binary.Write(w, binary.LittleEndian, id) + binary.Write(w, binary.LittleEndian, typ) + io.WriteString(w, body) + w.Write([]byte{0, 0}) +} + +func readTestPacket(r io.Reader) (id, typ int32, body string) { + var size int32 + binary.Read(r, binary.LittleEndian, &size) + payload := make([]byte, size) + io.ReadFull(r, payload) + id = int32(binary.LittleEndian.Uint32(payload[0:4])) + typ = int32(binary.LittleEndian.Uint32(payload[4:8])) + return id, typ, string(payload[headerSize : size-paddingSize]) +} + +// fakeServer speaks just enough Source RCON to exercise the client. +func fakeServer(t *testing.T, password string) string { + ln, err := net.Listen("tcp", "127.0.0.1:0") + if err != nil { + t.Fatal(err) + } + t.Cleanup(func() { ln.Close() }) + + go func() { + conn, err := ln.Accept() + if err != nil { + return + } + defer conn.Close() + + id, typ, body := readTestPacket(conn) + if typ != typeAuth { + return + } + respID := id + if body != password { + respID = -1 + } + writeTestPacket(conn, id, typeResponse, "") // empty value first + writeTestPacket(conn, respID, typeAuthResp, "") + if respID == -1 { + return + } + + cid, _, cbody := readTestPacket(conn) + out := "unknown command" + if cbody == "list" { + out = "There are 1 of a max of 20 players online: Steve" + } + writeTestPacket(conn, cid, typeResponse, out) + }() + + return ln.Addr().String() +} + +func TestClientExecute(t *testing.T) { + client, err := Dial(fakeServer(t, "secret"), "secret", time.Second) + if err != nil { + t.Fatal(err) + } + defer client.Close() + + out, err := client.Execute("list") + if err != nil { + t.Fatal(err) + } + if want := "There are 1 of a max of 20 players online: Steve"; out != want { + t.Errorf("Execute = %q, want %q", out, want) + } +} + +func TestClientAuthFailure(t *testing.T) { + _, err := Dial(fakeServer(t, "secret"), "wrong", time.Second) + if !errors.Is(err, ErrAuthFailed) { + t.Errorf("Dial err = %v, want ErrAuthFailed", err) + } +} |
