Description
Proposal #54136 (implemented in CL 436890 which is part of Go 1.20) added the "http".ResponseController
type, which allows manipulating per-request timeouts. This is especially useful for programs managing long-running HTTP connections such as Mercure.
However, testing HTTP handlers leveraging per-request timeouts is currently cumbersome (even if doable) because "net/http/httptest".ResponseRecorder
isn't compatible yet with "http".ResponseController
.
To make it fully compatible with response controllers and improve the testing experience, I propose the following additions to its public API:
type ResponseRecorder struct {
// ...
// ReadDeadline is the last read deadline that has been set using
// "net/http".ResponseController
ReadDeadline time.Time
// WriteDeadline is the last write deadline that has been set using
// "net/http".ResponseController
WriteDeadline time.Time
}
// SetReadDeadline allows using "net/http".ResponseController.SetReadDeadline()
// with the recorder.
//
// The deadline is recorded but is not enforced.
// To prevent flaky tests reads made after the deadline will work
// as if no deadline was set.
//
// To retrieve the deadline, use rw.ReadDeadline.
func (rw *ResponseRecorder) SetReadDeadline(deadline time.Time) error
// SetWriteDeadline allows using "net/http".ResponseController.SetWriteDeadline()
// with the recorder.
//
// The deadline is recorded but is not enforced.
// To prevent flaky tests writes made after the deadline will work
// as if no deadline was set.
//
// To retrieve the deadline, use rw.WriteDeadline.
func (rw *ResponseRecorder) SetWriteDeadline(deadline time.Time) error
All new methods are part of the contract that response types must honor to be usable with "HTTP".ResponseController
.
As discussed below, deadlines are recorded but not enforced to prevent flaky tests.
Proposal implementation: #60231