TestRequestTimeouts expects 504 when none of the body reached the app #50

Merged
clawbot merged 1 commits from issue-49-request-timeout-test into next 2026-10-04 06:09:23 +02:00
+27 -10
View File
@@ -5,8 +5,10 @@ import (
"io" "io"
"net" "net"
"net/http" "net/http"
"net/http/httptest"
"strconv" "strconv"
"sync" "sync"
"sync/atomic"
"testing" "testing"
"time" "time"
@@ -66,32 +68,47 @@ func TestRequestTimeouts(t *testing.T) {
t.Parallel() t.Parallel()
var ( var (
app *httptest.Server
appURL string appURL string
sendRequest func(*testing.T, string) net.Conn sendRequest func(*testing.T, string) net.Conn
appGotBody atomic.Bool
) )
if tc.appTakesNothing { if tc.appTakesNothing {
appURL, sendRequest = startAppThatTakesNothing(t), sendLargeBody appURL, sendRequest = startAppThatTakesNothing(t), sendLargeBody
} else { } else {
appURL, sendRequest = startApp(t, readBody).URL, sendPartOfBody app = startApp(t, func(_ http.ResponseWriter, r *http.Request) {
n, _ := io.Copy(io.Discard, r.Body)
appGotBody.Store(n > 0)
})
appURL, sendRequest = app.URL, sendPartOfBody
} }
addr, out := startProxy(t, appURL, tc.env) addr, out := startProxy(t, appURL, tc.env)
start := time.Now() start := time.Now()
conn := sendRequest(t, addr) got := readResponse(t, sendRequest(t, addr))
wantStatus(t, readResponse(t, conn), tc.want)
wantTimedOut(t, start) wantTimedOut(t, start)
wantLine(t, out.requestLine(t), tc.want, requestlog.ActionTimedOut)
want := tc.want
if app != nil {
// Close returns once the app has finished with the request.
app.Close()
// Until some of the body has reached the app, smallwebwaf
// waits on the app, and SPEC.md asks for 504; the timeout
// runs out then only if the test process is held up.
if !appGotBody.Load() {
want = http.StatusGatewayTimeout
}
}
wantStatus(t, got, want)
wantLine(t, out.requestLine(t), want, requestlog.ActionTimedOut)
}) })
} }
} }
// readBody is an app that reads the request body, then answers.
func readBody(_ http.ResponseWriter, r *http.Request) {
_, _ = io.Copy(io.Discard, r.Body)
}
// startAppThatTakesNothing starts an app that accepts connections and // startAppThatTakesNothing starts an app that accepts connections and
// never reads from them, and returns its URL. // never reads from them, and returns its URL.
func startAppThatTakesNothing(t *testing.T) string { func startAppThatTakesNothing(t *testing.T) string {