1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
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)
}
}
|