termd/internal/server/accesslog_test.go
2026-07-02 22:13:49 -03:00

94 lines
2.1 KiB
Go

package server_test
import (
"net/http"
"net/http/httptest"
"regexp"
"strings"
"syscall"
"testing"
"time"
"github.com/coder/websocket"
"termd/internal/api"
"termd/internal/client"
"termd/internal/server"
"termd/internal/session"
)
// Timestamp, method, path, status, latency.
var logLine = regexp.MustCompile(
`^\d{4}-\d{2}-\d{2}T\d{2}:\d{2}:\d{2}\.\d{3}(Z|[+-]\d{2}:\d{2}) (GET|POST|DELETE) \S+ \d{3} \d+(\.\d+)?(µs|ms|s)$`)
func TestAccessLog(t *testing.T) {
reg := session.NewRegistry()
var logs syncBuf
srv := httptest.NewServer(server.AccessLog(server.New(reg, ""), &logs))
t.Cleanup(func() {
for _, s := range reg.List() {
_ = s.Kill(syscall.SIGKILL)
}
srv.Close()
})
c := client.New(srv.URL, "")
// A 200, a 404, and a 101 websocket upgrade through the middleware.
if _, err := c.List(ctx()); err != nil {
t.Fatal(err)
}
resp, err := http.Get(srv.URL + "/sessions/nope/screen")
if err != nil {
t.Fatal(err)
}
resp.Body.Close()
info, err := c.Create(ctx(), api.CreateSessionRequest{Command: []string{"sh"}})
if err != nil {
t.Fatal(err)
}
conn, _, err := websocket.Dial(ctx(), c.AttachURL(info.ID), nil)
if err != nil {
t.Fatal(err)
}
conn.SetReadLimit(16 << 20)
_ = conn.Close(websocket.StatusNormalClosure, "done")
// The attach line only appears once its handler returns.
var lines []string
deadline := time.Now().Add(10 * time.Second)
for len(lines) < 4 && time.Now().Before(deadline) {
lines = nonEmptyLines(logs.String())
time.Sleep(10 * time.Millisecond)
}
if len(lines) < 4 {
t.Fatalf("want at least 4 log lines, got %d:\n%s", len(lines), logs.String())
}
for _, line := range lines {
if !logLine.MatchString(line) {
t.Errorf("malformed log line: %q", line)
}
}
all := logs.String()
for _, want := range []string{
"GET /sessions 200",
"GET /sessions/nope/screen 404",
"POST /sessions 201",
"/attach 101",
} {
if !strings.Contains(all, want) {
t.Errorf("log missing %q:\n%s", want, all)
}
}
}
func nonEmptyLines(s string) []string {
var out []string
for _, l := range strings.Split(s, "\n") {
if strings.TrimSpace(l) != "" {
out = append(out, l)
}
}
return out
}