add: test cases for rcon
This commit is contained in:
109
internal/pkg/rcon/mockrcon.go
Normal file
109
internal/pkg/rcon/mockrcon.go
Normal file
@@ -0,0 +1,109 @@
|
||||
package rcon
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"net"
|
||||
"sync"
|
||||
|
||||
"github.com/gorcon/rcon"
|
||||
)
|
||||
|
||||
// MockRCONServer simulates an RCON server for testing purposes
|
||||
type MockRCONServer struct {
|
||||
listener net.Listener
|
||||
Commands []string
|
||||
Errors []error
|
||||
Messages []string
|
||||
}
|
||||
|
||||
// Start starts the mock RCON server on a random available port
|
||||
func (m *MockRCONServer) Start() (func() *RCONResults, error) {
|
||||
listener, err := net.Listen("tcp", "127.0.0.1:0")
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("failed to start mock server: %w", err)
|
||||
}
|
||||
m.listener = listener
|
||||
|
||||
results := &RCONResults{}
|
||||
done := sync.WaitGroup{}
|
||||
|
||||
done.Go(func() {
|
||||
for {
|
||||
conn, err := listener.Accept()
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
go m.handleConnection(conn, results)
|
||||
}
|
||||
})
|
||||
|
||||
return func() *RCONResults {
|
||||
m.stop()
|
||||
done.Wait()
|
||||
return results
|
||||
}, nil
|
||||
}
|
||||
|
||||
// Stop stops the mock RCON server
|
||||
func (m *MockRCONServer) stop() error {
|
||||
if m.listener != nil {
|
||||
return m.listener.Close()
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
// Address returns the address the mock server is listening on
|
||||
func (m *MockRCONServer) Address() string {
|
||||
if m.listener != nil {
|
||||
return m.listener.Addr().String()
|
||||
}
|
||||
return ""
|
||||
}
|
||||
|
||||
// handleConnection handles individual client connections
|
||||
func (m *MockRCONServer) handleConnection(conn net.Conn, results *RCONResults) {
|
||||
defer conn.Close()
|
||||
|
||||
for {
|
||||
packet := &rcon.Packet{}
|
||||
if _, err := packet.ReadFrom(conn); err != nil {
|
||||
results.AppendError(err)
|
||||
return
|
||||
}
|
||||
|
||||
results.AppendMessage(packet.Body())
|
||||
|
||||
var respPacket *rcon.Packet
|
||||
switch packet.Type {
|
||||
case rcon.SERVERDATA_AUTH:
|
||||
respPacket = rcon.NewPacket(rcon.SERVERDATA_AUTH_RESPONSE, packet.ID, "")
|
||||
case rcon.SERVERDATA_EXECCOMMAND:
|
||||
respPacket = rcon.NewPacket(rcon.SERVERDATA_RESPONSE_VALUE, packet.ID, "")
|
||||
default:
|
||||
results.AppendError(fmt.Errorf("unknown packet: %v", packet.Type))
|
||||
return
|
||||
}
|
||||
if _, err := respPacket.WriteTo(conn); err != nil {
|
||||
results.AppendError(err)
|
||||
return
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
type RCONResults struct {
|
||||
mu sync.Mutex
|
||||
Messages []string
|
||||
Errors []error
|
||||
}
|
||||
|
||||
func (r *RCONResults) AppendError(err error) {
|
||||
r.mu.Lock()
|
||||
defer r.mu.Unlock()
|
||||
r.Errors = append(r.Errors, err)
|
||||
}
|
||||
|
||||
func (r *RCONResults) AppendMessage(msg string) {
|
||||
r.mu.Lock()
|
||||
defer r.mu.Unlock()
|
||||
r.Messages = append(r.Messages, msg)
|
||||
}
|
||||
Reference in New Issue
Block a user