check / check (push) Successful in 1m10s
A buffer failure on POST /api/v1/reports now returns 500 instead of a false `ok`, so clients can retry. An over-limit body returns 413 (errors.As on `*http.MaxBytesError`); malformed JSON stays 400. A MaxBodyBytes middleware (1 MiB) caps every route, rejecting an oversized Content-Length up front and capping the read otherwise; a route group can only lower that limit. The raw geo blob is no longer logged, only its length; client_id, timestamp and decode error text are length-bounded before logging. A decodeJSON handler helper is added. Panic recovery routes the stack through slog as structured JSON. Storage failure uses 500: a full buffer or write error is server-side and retryable. Model: opus-5-5
68 lines
1.5 KiB
Go
68 lines
1.5 KiB
Go
package server_test
|
|
|
|
import (
|
|
"net/http"
|
|
"net/http/httptest"
|
|
"strings"
|
|
"testing"
|
|
|
|
"sneak.berlin/go/netwatch/internal/config"
|
|
"sneak.berlin/go/netwatch/internal/globals"
|
|
"sneak.berlin/go/netwatch/internal/handlers"
|
|
"sneak.berlin/go/netwatch/internal/healthcheck"
|
|
"sneak.berlin/go/netwatch/internal/logger"
|
|
"sneak.berlin/go/netwatch/internal/middleware"
|
|
"sneak.berlin/go/netwatch/internal/reportbuf"
|
|
"sneak.berlin/go/netwatch/internal/server"
|
|
|
|
"go.uber.org/fx"
|
|
"go.uber.org/fx/fxtest"
|
|
)
|
|
|
|
// TestHealthCheckRejectsOversizeBody sends the health check, which
|
|
// never reads its body, a body one byte over the limit. Only the
|
|
// router-wide body limit can reject it.
|
|
func TestHealthCheckRejectsOversizeBody(t *testing.T) {
|
|
t.Parallel()
|
|
|
|
var srv *server.Server
|
|
|
|
// The same constructors as main, never started: SetupRoutes is
|
|
// called directly, so nothing listens.
|
|
app := fxtest.New(t,
|
|
fx.Provide(
|
|
config.New,
|
|
globals.New,
|
|
handlers.New,
|
|
healthcheck.New,
|
|
logger.New,
|
|
middleware.New,
|
|
reportbuf.New,
|
|
server.New,
|
|
),
|
|
fx.Populate(&srv),
|
|
)
|
|
|
|
err := app.Err()
|
|
if err != nil {
|
|
t.Fatalf("build server: %v", err)
|
|
}
|
|
|
|
srv.SetupRoutes()
|
|
|
|
rec := httptest.NewRecorder()
|
|
req := httptest.NewRequestWithContext(t.Context(),
|
|
http.MethodGet, "/.well-known/healthcheck",
|
|
strings.NewReader(
|
|
strings.Repeat("x", int(server.MaxRequestBodyBytes)+1),
|
|
),
|
|
)
|
|
|
|
srv.ServeHTTP(rec, req)
|
|
|
|
if rec.Code != http.StatusRequestEntityTooLarge {
|
|
t.Fatalf("status = %d, want %d",
|
|
rec.Code, http.StatusRequestEntityTooLarge)
|
|
}
|
|
}
|