test: skip APF header assertions after request timeout

This commit is contained in:
Aman Shrivastava
2025-12-23 19:40:25 +05:30
parent c180d6762d
commit 8d0efb4805

View File

@@ -712,7 +712,7 @@ func TestPriorityAndFairnessWithPanicRecoveryAndTimeoutFilter(t *testing.T) {
firstRequestPathPanic, secondRequestPathShouldWork := "/request/panic-as-designed", "/request/should-succeed-as-expected"
firstHandlerDoneCh, secondHandlerDoneCh := make(chan struct{}), make(chan struct{})
requestHandler := http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
headerMatcher.inspect(t, w, fsName, plName)
headerMatcher.inspect(t, w, r.Context(), fsName, plName)
switch {
case r.URL.Path == firstRequestPathPanic:
close(firstHandlerDoneCh)
@@ -785,7 +785,7 @@ func TestPriorityAndFairnessWithPanicRecoveryAndTimeoutFilter(t *testing.T) {
rquestTimesOutPath := "/request/time-out-as-designed"
reqHandlerCompletedCh, callerRoundTripDoneCh := make(chan struct{}), make(chan struct{})
requestHandler := http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
headerMatcher.inspect(t, w, fsName, plName)
headerMatcher.inspect(t, w, r.Context(), fsName, plName)
if r.URL.Path == rquestTimesOutPath {
defer close(reqHandlerCompletedCh)
@@ -858,7 +858,7 @@ func TestPriorityAndFairnessWithPanicRecoveryAndTimeoutFilter(t *testing.T) {
reqHandlerErrCh, callerRoundTripDoneCh := make(chan error, 1), make(chan struct{})
rquestTimesOutPath := "/request/time-out-as-designed"
requestHandler := http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
headerMatcher.inspect(t, w, fsName, plName)
headerMatcher.inspect(t, w, r.Context(), fsName, plName)
if r.URL.Path == rquestTimesOutPath {
<-callerRoundTripDoneCh
@@ -937,7 +937,7 @@ func TestPriorityAndFairnessWithPanicRecoveryAndTimeoutFilter(t *testing.T) {
rquestTimesOutPath := "/request/time-out-as-designed"
reqHandlerErrCh, callerRoundTripDoneCh := make(chan error, 1), make(chan struct{})
requestHandler := http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
headerMatcher.inspect(t, w, fsName, plName)
headerMatcher.inspect(t, w, r.Context(), fsName, plName)
if r.URL.Path == rquestTimesOutPath {
@@ -1016,7 +1016,7 @@ func TestPriorityAndFairnessWithPanicRecoveryAndTimeoutFilter(t *testing.T) {
firstReqHandlerErrCh, firstReqInProgressCh := make(chan error, 1), make(chan struct{})
firstReqRoundTripDoneCh, secondReqRoundTripDoneCh := make(chan struct{}), make(chan struct{})
requestHandler := http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
headerMatcher.inspect(t, w, fsName, plName)
headerMatcher.inspect(t, w, r.Context(), fsName, plName)
switch {
case r.URL.Path == firstRequestTimesOutPath:
close(firstReqInProgressCh)
@@ -1188,28 +1188,35 @@ func newHTTP2ServerWithClient(handler http.Handler, clientTimeout time.Duration)
type headerMatcher struct{}
// verifies that the expected flow schema and priority level UIDs are attached to the header.
func (m *headerMatcher) inspect(t *testing.T, w http.ResponseWriter, expectedFS, expectedPL string) {
func (m *headerMatcher) inspect(t *testing.T, w http.ResponseWriter, ctx context.Context, expectedFS, expectedPL string) {
t.Helper()
err := func() error {
if w == nil {
return fmt.Errorf("expected a non nil HTTP response")
}
key := flowcontrol.ResponseHeaderMatchedFlowSchemaUID
if value := w.Header().Get(key); expectedFS != value {
return fmt.Errorf("expected HTTP header %s to have value %q, but got: %q", key, expectedFS, value)
}
key = flowcontrol.ResponseHeaderMatchedPriorityLevelConfigurationUID
if value := w.Header().Get(key); expectedPL != value {
return fmt.Errorf("expected HTTP header %s to have value %q, but got %q", key, expectedPL, value)
}
return nil
}()
if err == nil {
if w == nil {
t.Errorf("expected a non nil HTTP response")
return
}
t.Errorf("Expected APF headers to match, but got: %v", err)
checkHeader := func(key, expected string) {
actual := w.Header().Get(key)
if actual == expected {
return
}
// Header writes are best-effort once the request context is canceled.
if actual == "" {
select {
case <-ctx.Done():
t.Logf("Skipping APF header assertion for %s: request context already done", key)
return
default:
}
}
t.Errorf("expected HTTP header %s to have value %q, but got: %q", key, expected, actual)
}
checkHeader(flowcontrol.ResponseHeaderMatchedFlowSchemaUID, expectedFS)
checkHeader(flowcontrol.ResponseHeaderMatchedPriorityLevelConfigurationUID, expectedPL)
}
// when a request panics, http2 resets the stream with an INTERNAL_ERROR message