package main import ( "bytes" "context" "errors" "net" "testing" "time" "github.com/gorcon/rcon" ) func TestMultipart(t *testing.T) { listener, err := net.Listen("tcp", "127.0.0.1:0") if err != nil { t.Fatal(err) } defer listener.Close() done := make(chan error, 1) go func() { conn, err := listener.Accept() if err != nil { done <- err return } defer conn.Close() var packet rcon.Packet if _, err := packet.ReadFrom(conn); err != nil { done <- err return } if _, err := rcon.NewPacket(2, packet.ID, "").WriteTo(conn); err != nil { done <- err return } if _, err := packet.ReadFrom(conn); err != nil { done <- err return } commandID := packet.ID if _, err := rcon.NewPacket(0, commandID, "first packet\n").WriteTo(conn); err != nil { done <- err return } if _, err := packet.ReadFrom(conn); err != nil { done <- err return } markerID := packet.ID for _, response := range []*rcon.Packet{ rcon.NewPacket(0, commandID, "second packet"), rcon.NewPacket(0, markerID, "Unknown request 0"), } { if _, err := response.WriteTo(conn); err != nil { done <- err return } } done <- nil }() output, err := execute(context.Background(), listener.Addr().String(), "synthetic", "help") if err != nil { t.Fatal(err) } if output != "first packet\nsecond packet" { t.Fatalf("output=%q", output) } if err := <-done; err != nil { t.Fatal(err) } } func TestSplitAuth(t *testing.T) { client, server := net.Pipe() defer client.Close() defer server.Close() _ = client.SetDeadline(time.Now().Add(time.Second)) done := make(chan error, 1) go func() { defer server.Close() var request rcon.Packet if _, err := request.ReadFrom(server); err != nil { done <- err return } var reply bytes.Buffer _, _ = rcon.NewPacket(rcon.SERVERDATA_AUTH_RESPONSE, request.ID, "").WriteTo(&reply) packet := reply.Bytes() for _, part := range [][]byte{packet[:len(packet)-1], packet[len(packet)-1:]} { if _, err := server.Write(part); err != nil { done <- err return } } _, err := rcon.NewPacket(rcon.SERVERDATA_RESPONSE_VALUE, cmdID, "ok").WriteTo(server) done <- err }() if err := authenticate(client, "synthetic-password"); err != nil { t.Fatal(err) } var response rcon.Packet if _, err := response.ReadFrom(client); err != nil { t.Fatal(err) } if response.ID != cmdID || response.Body() != "ok" { t.Fatalf("id=%d body=%q", response.ID, response.Body()) } if err := <-done; err != nil { t.Fatal(err) } } func TestAuthFailure(t *testing.T) { client, server := net.Pipe() defer client.Close() defer server.Close() _ = client.SetDeadline(time.Now().Add(time.Second)) go func() { defer server.Close() var request rcon.Packet _, _ = request.ReadFrom(server) _, _ = rcon.NewPacket(rcon.SERVERDATA_AUTH_RESPONSE, -1, "").WriteTo(server) }() if err := authenticate(client, "wrong-password"); !errors.Is(err, rcon.ErrAuthFailed) { t.Fatalf("error=%v", err) } }