Compare commits
1
Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
a3cfec09df |
@@ -23,10 +23,9 @@ Rationale, Design, TODO, License, Author) if any are still missing.
|
|||||||
|
|
||||||
# Completed Steps
|
# Completed Steps
|
||||||
|
|
||||||
- 2026-09-21: server timeout test now drives `Run` and asserts the
|
- 2026-09-28: the server timeout test now drives `Run` and checks the
|
||||||
served `http.Server` carries the timeouts; corrected the inverted
|
`http.Server` it serves carries the timeouts; corrected the `ReadTimeout`
|
||||||
`ReadTimeout` rationale note (#120).
|
note in that test (closes #120).
|
||||||
|
|
||||||
- 2026-09-28: upaas deploy readiness — runtime image runs as unprivileged
|
- 2026-09-28: upaas deploy readiness — runtime image runs as unprivileged
|
||||||
`dnswatcher`, Docker `HEALTHCHECK`, startup fails when the data directory is
|
`dnswatcher`, Docker `HEALTHCHECK`, startup fails when the data directory is
|
||||||
not writable, README "Running under upaas" (closes #147).
|
not writable, README "Running under upaas" (closes #147).
|
||||||
@@ -34,7 +33,6 @@ Rationale, Design, TODO, License, Author) if any are still missing.
|
|||||||
`internal/healthcheck`, and `internal/logger` (closes #110).
|
`internal/healthcheck`, and `internal/logger` (closes #110).
|
||||||
- 2026-09-21: `go mod tidy` dropped the redundant `golang.org/x/sync`
|
- 2026-09-21: `go mod tidy` dropped the redundant `golang.org/x/sync`
|
||||||
`// indirect` line so `script/bootstrap` leaves a clean tree (#132)
|
`// indirect` line so `script/bootstrap` leaves a clean tree (#132)
|
||||||
|
|
||||||
- 2026-08-10: comment-only corrections to `script/bootstrap`,
|
- 2026-08-10: comment-only corrections to `script/bootstrap`,
|
||||||
`script/cibuild`, and `Dockerfile.lint`. The `goimports` pin in
|
`script/cibuild`, and `Dockerfile.lint`. The `goimports` pin in
|
||||||
`script/bootstrap` was justified by a claim that `script/fmt-check`
|
`script/bootstrap` was justified by a claim that `script/fmt-check`
|
||||||
|
|||||||
@@ -55,10 +55,7 @@ func buildServer(t *testing.T) *server.Server {
|
|||||||
// TestRunWiresSocketTimeouts pins that the http.Server the running
|
// TestRunWiresSocketTimeouts pins that the http.Server the running
|
||||||
// server actually serves — the one Run builds and hands to
|
// server actually serves — the one Run builds and hands to
|
||||||
// ListenAndServe — carries every socket-level timeout, plus the two
|
// ListenAndServe — carries every socket-level timeout, plus the two
|
||||||
// relationships the values must satisfy. Earlier tests asserted these
|
// relationships the values must satisfy.
|
||||||
// on newHTTPServer directly, which left the call site unguarded: a Run
|
|
||||||
// that built its http.Server inline would drop every timeout with the
|
|
||||||
// suite still green (https://git.eeqj.de/sneak/dnswatcher/issues/120).
|
|
||||||
//
|
//
|
||||||
// Run is driven to completion with an unbindable port: it builds and
|
// Run is driven to completion with an unbindable port: it builds and
|
||||||
// stores s.httpServer, then ListenAndServe fails at once and Run
|
// stores s.httpServer, then ListenAndServe fails at once and Run
|
||||||
@@ -66,16 +63,13 @@ func buildServer(t *testing.T) *server.Server {
|
|||||||
// goroutine after Run returns, so reading s.httpServer is free of any
|
// goroutine after Run returns, so reading s.httpServer is free of any
|
||||||
// data race. Nothing here measures elapsed time.
|
// data race. Nothing here measures elapsed time.
|
||||||
//
|
//
|
||||||
// On the ReadTimeout >= ReadHeaderTimeout relationship: a smaller
|
// ReadTimeout must be at least ReadHeaderTimeout. net/http reads the
|
||||||
// ReadTimeout does NOT make the header phase unreachable. net/http's
|
// headers under ReadHeaderTimeout, then sets the read deadline for the
|
||||||
// (*Server).readHeaderTimeout applies ReadHeaderTimeout directly, so
|
// rest of the request to ReadTimeout, counted from when it started
|
||||||
// the header read keeps its full budget. What breaks is the
|
// reading the request. If ReadTimeout were smaller, a request whose
|
||||||
// whole-request deadline: once the headers are read, readRequest
|
// headers arrived after ReadTimeout but within ReadHeaderTimeout would
|
||||||
// installs a read deadline of t0+ReadTimeout, which is already in the
|
// get a read deadline that had already passed, so reading its body
|
||||||
// past when ReadTimeout is the smaller value, severing the request.
|
// would fail at once.
|
||||||
// Verified against the pinned go1.25 net/http (Dockerfile golang
|
|
||||||
// 1.25-alpine; go.mod go 1.25.5): src/net/http/server.go readRequest
|
|
||||||
// and (*Server).readHeaderTimeout.
|
|
||||||
func TestRunWiresSocketTimeouts(t *testing.T) {
|
func TestRunWiresSocketTimeouts(t *testing.T) {
|
||||||
// Sets an env var and touches viper global state, so like the
|
// Sets an env var and touches viper global state, so like the
|
||||||
// config tests it cannot use t.Parallel.
|
// config tests it cannot use t.Parallel.
|
||||||
|
|||||||
Reference in New Issue
Block a user