Merge pull request #115686 from tkashem/apf-test-fix

apiserver: fix APF tests, use T functions on the test goroutine
This commit is contained in:
Kubernetes Prow Robot 2023-02-21 17:25:56 -08:00 committed by GitHub
commit 59ec35eb2d
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23

View File

@ -682,12 +682,13 @@ func TestPriorityAndFairnessWithPanicRecoveryAndTimeoutFilter(t *testing.T) {
stopCh := make(chan struct{}) stopCh := make(chan struct{})
controller, controllerCompletedCh := startAPFController(t, stopCh, apfConfiguration, serverConcurrency, requestTimeout/4, plName, plConcurrency) controller, controllerCompletedCh := startAPFController(t, stopCh, apfConfiguration, serverConcurrency, requestTimeout/4, plName, plConcurrency)
headerMatcher := headerMatcher{}
var executed bool var executed bool
// we will raise a panic for the first request. // we will raise a panic for the first request.
firstRequestPathPanic := "/request/panic-as-designed" firstRequestPathPanic := "/request/panic-as-designed"
requestHandler := http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { requestHandler := http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
executed = true executed = true
expectMatchingAPFHeaders(t, w, fsName, plName) headerMatcher.inspect(w, fsName, plName)
if r.URL.Path == firstRequestPathPanic { if r.URL.Path == firstRequestPathPanic {
panic(fmt.Errorf("request handler panic'd as designed - %#v", r.RequestURI)) panic(fmt.Errorf("request handler panic'd as designed - %#v", r.RequestURI))
@ -724,6 +725,10 @@ func TestPriorityAndFairnessWithPanicRecoveryAndTimeoutFilter(t *testing.T) {
t.Errorf("Expected HTTP status code: %d for request: %q, but got: %#v", http.StatusOK, secondRequestPathShouldWork, response) t.Errorf("Expected HTTP status code: %d for request: %q, but got: %#v", http.StatusOK, secondRequestPathShouldWork, response)
} }
for _, err := range headerMatcher.errors() {
t.Errorf("Expected APF headers to match, but got: %v", err)
}
close(stopCh) close(stopCh)
t.Log("Waiting for the controller to shutdown") t.Log("Waiting for the controller to shutdown")
@ -747,12 +752,13 @@ func TestPriorityAndFairnessWithPanicRecoveryAndTimeoutFilter(t *testing.T) {
stopCh := make(chan struct{}) stopCh := make(chan struct{})
controller, controllerCompletedCh := startAPFController(t, stopCh, apfConfiguration, serverConcurrency, requestTimeout/4, plName, plConcurrency) controller, controllerCompletedCh := startAPFController(t, stopCh, apfConfiguration, serverConcurrency, requestTimeout/4, plName, plConcurrency)
headerMatcher := headerMatcher{}
var executed bool var executed bool
rquestTimesOutPath := "/request/time-out-as-designed" rquestTimesOutPath := "/request/time-out-as-designed"
reqHandlerCompletedCh, callerRoundTripDoneCh := make(chan struct{}), make(chan struct{}) reqHandlerCompletedCh, callerRoundTripDoneCh := make(chan struct{}), make(chan struct{})
requestHandler := http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { requestHandler := http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
executed = true executed = true
expectMatchingAPFHeaders(t, w, fsName, plName) headerMatcher.inspect(w, fsName, plName)
if r.URL.Path == rquestTimesOutPath { if r.URL.Path == rquestTimesOutPath {
defer close(reqHandlerCompletedCh) defer close(reqHandlerCompletedCh)
@ -795,6 +801,10 @@ func TestPriorityAndFairnessWithPanicRecoveryAndTimeoutFilter(t *testing.T) {
t.Errorf("Expected HTTP status code: %d for request: %q, but got: %#v", http.StatusGatewayTimeout, rquestTimesOutPath, response) t.Errorf("Expected HTTP status code: %d for request: %q, but got: %#v", http.StatusGatewayTimeout, rquestTimesOutPath, response)
} }
for _, err := range headerMatcher.errors() {
t.Errorf("Expected APF headers to match, but got: %v", err)
}
close(stopCh) close(stopCh)
t.Log("Waiting for the controller to shutdown") t.Log("Waiting for the controller to shutdown")
@ -818,11 +828,12 @@ func TestPriorityAndFairnessWithPanicRecoveryAndTimeoutFilter(t *testing.T) {
stopCh := make(chan struct{}) stopCh := make(chan struct{})
controller, controllerCompletedCh := startAPFController(t, stopCh, apfConfiguration, serverConcurrency, requestTimeout/4, plName, plConcurrency) controller, controllerCompletedCh := startAPFController(t, stopCh, apfConfiguration, serverConcurrency, requestTimeout/4, plName, plConcurrency)
headerMatcher := headerMatcher{}
var innerHandlerWriteErr error var innerHandlerWriteErr error
reqHandlerCompletedCh, callerRoundTripDoneCh := make(chan struct{}), make(chan struct{}) reqHandlerCompletedCh, callerRoundTripDoneCh := make(chan struct{}), make(chan struct{})
rquestTimesOutPath := "/request/time-out-as-designed" rquestTimesOutPath := "/request/time-out-as-designed"
requestHandler := http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { requestHandler := http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
expectMatchingAPFHeaders(t, w, fsName, plName) headerMatcher.inspect(w, fsName, plName)
if r.URL.Path == rquestTimesOutPath { if r.URL.Path == rquestTimesOutPath {
defer close(reqHandlerCompletedCh) defer close(reqHandlerCompletedCh)
@ -868,6 +879,10 @@ func TestPriorityAndFairnessWithPanicRecoveryAndTimeoutFilter(t *testing.T) {
t.Errorf("Expected HTTP status code: %d for request: %q, but got: %#v", http.StatusGatewayTimeout, rquestTimesOutPath, response) t.Errorf("Expected HTTP status code: %d for request: %q, but got: %#v", http.StatusGatewayTimeout, rquestTimesOutPath, response)
} }
for _, err := range headerMatcher.errors() {
t.Errorf("Expected APF headers to match, but got: %v", err)
}
close(stopCh) close(stopCh)
t.Log("Waiting for the controller to shutdown") t.Log("Waiting for the controller to shutdown")
@ -891,11 +906,12 @@ func TestPriorityAndFairnessWithPanicRecoveryAndTimeoutFilter(t *testing.T) {
stopCh := make(chan struct{}) stopCh := make(chan struct{})
controller, controllerCompletedCh := startAPFController(t, stopCh, apfConfiguration, serverConcurrency, requestTimeout/4, plName, plConcurrency) controller, controllerCompletedCh := startAPFController(t, stopCh, apfConfiguration, serverConcurrency, requestTimeout/4, plName, plConcurrency)
headerMatcher := headerMatcher{}
var innerHandlerWriteErr error var innerHandlerWriteErr error
rquestTimesOutPath := "/request/time-out-as-designed" rquestTimesOutPath := "/request/time-out-as-designed"
reqHandlerCompletedCh, callerRoundTripDoneCh := make(chan struct{}), make(chan struct{}) reqHandlerCompletedCh, callerRoundTripDoneCh := make(chan struct{}), make(chan struct{})
requestHandler := http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { requestHandler := http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
expectMatchingAPFHeaders(t, w, fsName, plName) headerMatcher.inspect(w, fsName, plName)
if r.URL.Path == rquestTimesOutPath { if r.URL.Path == rquestTimesOutPath {
defer close(reqHandlerCompletedCh) defer close(reqHandlerCompletedCh)
@ -932,6 +948,10 @@ func TestPriorityAndFairnessWithPanicRecoveryAndTimeoutFilter(t *testing.T) {
} }
expectResetStreamError(t, err) expectResetStreamError(t, err)
for _, err := range headerMatcher.errors() {
t.Errorf("Expected APF headers to match, but got: %v", err)
}
close(stopCh) close(stopCh)
t.Log("Waiting for the controller to shutdown") t.Log("Waiting for the controller to shutdown")
@ -961,6 +981,7 @@ func TestPriorityAndFairnessWithPanicRecoveryAndTimeoutFilter(t *testing.T) {
stopCh := make(chan struct{}) stopCh := make(chan struct{})
controller, controllerCompletedCh := startAPFController(t, stopCh, apfConfiguration, serverConcurrency, requestTimeout/4, plName, plConcurrency) controller, controllerCompletedCh := startAPFController(t, stopCh, apfConfiguration, serverConcurrency, requestTimeout/4, plName, plConcurrency)
headerMatcher := headerMatcher{}
var firstRequestInnerHandlerWriteErr error var firstRequestInnerHandlerWriteErr error
var secondRequestExecuted bool var secondRequestExecuted bool
firstRequestTimesOutPath := "/request/first/time-out-as-designed" firstRequestTimesOutPath := "/request/first/time-out-as-designed"
@ -968,7 +989,7 @@ func TestPriorityAndFairnessWithPanicRecoveryAndTimeoutFilter(t *testing.T) {
firstReqHandlerCompletedCh, firstReqInProgressCh := make(chan struct{}), make(chan struct{}) firstReqHandlerCompletedCh, firstReqInProgressCh := make(chan struct{}), make(chan struct{})
firstReqRoundTripDoneCh, secondReqRoundTripDoneCh := make(chan struct{}), make(chan struct{}) firstReqRoundTripDoneCh, secondReqRoundTripDoneCh := make(chan struct{}), make(chan struct{})
requestHandler := http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { requestHandler := http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
expectMatchingAPFHeaders(t, w, fsName, plName) headerMatcher.inspect(w, fsName, plName)
if r.URL.Path == firstRequestTimesOutPath { if r.URL.Path == firstRequestTimesOutPath {
defer close(firstReqHandlerCompletedCh) defer close(firstReqHandlerCompletedCh)
@ -1071,6 +1092,10 @@ func TestPriorityAndFairnessWithPanicRecoveryAndTimeoutFilter(t *testing.T) {
t.Errorf("Expected HTTP status code: %d or %d for request: %q, but got: %#+v", http.StatusTooManyRequests, http.StatusGatewayTimeout, secondRequestEnqueuedPath, secondReqResult.response) t.Errorf("Expected HTTP status code: %d or %d for request: %q, but got: %#+v", http.StatusTooManyRequests, http.StatusGatewayTimeout, secondRequestEnqueuedPath, secondReqResult.response)
} }
for _, err := range headerMatcher.errors() {
t.Errorf("Expected APF headers to match, but got: %v", err)
}
close(stopCh) close(stopCh)
t.Log("Waiting for the controller to shutdown") t.Log("Waiting for the controller to shutdown")
@ -1137,21 +1162,42 @@ func newHTTP2ServerWithClient(handler http.Handler, clientTimeout time.Duration)
} }
} }
type headerMatcher struct {
lock sync.Mutex
errsGot []error
}
// verifies that the expected flow schema and priority level UIDs are attached to the header. // verifies that the expected flow schema and priority level UIDs are attached to the header.
func expectMatchingAPFHeaders(t *testing.T, w http.ResponseWriter, expectedFS, expectedPL string) { func (m *headerMatcher) inspect(w http.ResponseWriter, expectedFS, expectedPL string) {
err := func() error {
if w == nil { if w == nil {
t.Fatal("expected a non nil HTTP response") return fmt.Errorf("expected a non nil HTTP response")
} }
key := flowcontrol.ResponseHeaderMatchedFlowSchemaUID key := flowcontrol.ResponseHeaderMatchedFlowSchemaUID
if value := w.Header().Get(key); expectedFS != value { if value := w.Header().Get(key); expectedFS != value {
t.Fatalf("expected HTTP header %s to have value %q, but got: %q", key, expectedFS, value) return fmt.Errorf("expected HTTP header %s to have value %q, but got: %q", key, expectedFS, value)
} }
key = flowcontrol.ResponseHeaderMatchedPriorityLevelConfigurationUID key = flowcontrol.ResponseHeaderMatchedPriorityLevelConfigurationUID
if value := w.Header().Get(key); expectedPL != value { if value := w.Header().Get(key); expectedPL != value {
t.Fatalf("expected HTTP header %s to have value %q, but got %q", 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 {
return
}
m.lock.Lock()
defer m.lock.Unlock()
m.errsGot = append(m.errsGot, err)
}
func (m *headerMatcher) errors() []error {
m.lock.Lock()
defer m.lock.Unlock()
return m.errsGot[:]
} }
// when a request panics, http2 resets the stream with an INTERNAL_ERROR message // when a request panics, http2 resets the stream with an INTERNAL_ERROR message