summaryrefslogtreecommitdiff
path: root/adapters/rcon/rcon_test.go
diff options
context:
space:
mode:
authorElizabeth Alexander Hunt <me@liz.coffee>2026-06-20 09:40:07 -0700
committerElizabeth Alexander Hunt <me@liz.coffee>2026-06-20 09:40:07 -0700
commitfb653292612eddca5b088ed88466c546d1597107 (patch)
tree900ed32e066812688858ed3bb15128c41bb78054 /adapters/rcon/rcon_test.go
downloadpenguins.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.go91
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)
+ }
+}