94 lines
2.1 KiB
Go
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
|
|
}
|