75 lines
2.6 KiB
Go
75 lines
2.6 KiB
Go
|
|
package main
|
||
|
|
|
||
|
|
import (
|
||
|
|
"context"
|
||
|
|
"errors"
|
||
|
|
"net/http"
|
||
|
|
"net/http/httptest"
|
||
|
|
"strings"
|
||
|
|
"testing"
|
||
|
|
)
|
||
|
|
|
||
|
|
func TestCommandBoundary(t *testing.T) {
|
||
|
|
for _, tc := range []struct {
|
||
|
|
name, method, body string
|
||
|
|
allow bool
|
||
|
|
authErr error
|
||
|
|
status, calls int
|
||
|
|
}{
|
||
|
|
{"viewer", "POST", `{"command":"stop"}`, false, nil, 403, 0},
|
||
|
|
{"auth failure", "POST", `{"command":"stop"}`, false, errors.New("offline"), 503, 0},
|
||
|
|
{"query refresh", "GET", `{"command":"stop"}`, true, nil, 405, 0},
|
||
|
|
{"empty", "POST", `{"command":" "}`, true, nil, 400, 0},
|
||
|
|
{"newline", "POST", `{"command":"list\nstop"}`, true, nil, 400, 0},
|
||
|
|
{"nul", "POST", `{"command":"list\u0000stop"}`, true, nil, 400, 0},
|
||
|
|
{"oversized", "POST", `{"command":"` + strings.Repeat("x", 1001) + `"}`, true, nil, 400, 0},
|
||
|
|
{"admin", "POST", `{"command":"list"}`, true, nil, 200, 1},
|
||
|
|
} {
|
||
|
|
t.Run(tc.name, func(t *testing.T) {
|
||
|
|
calls := 0
|
||
|
|
c := &console{allowed: func(*http.Request) (bool, error) { return tc.allow, tc.authErr }, execute: func(context.Context, string) (string, error) { calls++; return "Nobody online", nil }}
|
||
|
|
w := httptest.NewRecorder()
|
||
|
|
c.routes().ServeHTTP(w, httptest.NewRequest(tc.method, "/command", strings.NewReader(tc.body)))
|
||
|
|
if w.Code != tc.status || calls != tc.calls {
|
||
|
|
t.Fatalf("status=%d calls=%d", w.Code, calls)
|
||
|
|
}
|
||
|
|
})
|
||
|
|
}
|
||
|
|
}
|
||
|
|
|
||
|
|
func TestNoRetry(t *testing.T) {
|
||
|
|
calls := 0
|
||
|
|
c := &console{allowed: func(*http.Request) (bool, error) { return true, nil }, execute: func(context.Context, string) (string, error) { calls++; return "", errors.New("lost response") }}
|
||
|
|
w := httptest.NewRecorder()
|
||
|
|
c.routes().ServeHTTP(w, httptest.NewRequest("POST", "/command", strings.NewReader(`{"command":"say once"}`)))
|
||
|
|
if w.Code != 502 || calls != 1 {
|
||
|
|
t.Fatalf("status=%d calls=%d", w.Code, calls)
|
||
|
|
}
|
||
|
|
}
|
||
|
|
|
||
|
|
func TestHealth(t *testing.T) {
|
||
|
|
for _, tc := range []struct {
|
||
|
|
name string
|
||
|
|
allow bool
|
||
|
|
err error
|
||
|
|
status, calls int
|
||
|
|
}{
|
||
|
|
{"viewer", false, nil, 403, 0},
|
||
|
|
{"admin", true, nil, 200, 1},
|
||
|
|
{"unavailable RCON", true, errors.New("offline"), 502, 1},
|
||
|
|
} {
|
||
|
|
t.Run(tc.name, func(t *testing.T) {
|
||
|
|
checks, commands := 0, 0
|
||
|
|
c := &console{
|
||
|
|
allowed: func(*http.Request) (bool, error) { return tc.allow, nil },
|
||
|
|
check: func(context.Context) error { checks++; return tc.err },
|
||
|
|
execute: func(context.Context, string) (string, error) { commands++; return "", nil },
|
||
|
|
}
|
||
|
|
w := httptest.NewRecorder()
|
||
|
|
c.routes().ServeHTTP(w, httptest.NewRequest("GET", "/health", nil))
|
||
|
|
if w.Code != tc.status || checks != tc.calls || commands != 0 {
|
||
|
|
t.Fatalf("status=%d checks=%d commands=%d", w.Code, checks, commands)
|
||
|
|
}
|
||
|
|
})
|
||
|
|
}
|
||
|
|
}
|