Merge pull request #115686 from tkashem/apf-test-fix
apiserver: fix APF tests, use T functions on the test goroutine Kubernetes-commit: 59ec35eb2dbfa92cb1466d8c5a7c0796dfd1eed0
This commit is contained in:
commit
83c4b5b2c6
4
go.mod
4
go.mod
|
@ -44,7 +44,7 @@ require (
|
|||
gopkg.in/square/go-jose.v2 v2.2.2
|
||||
k8s.io/api v0.0.0-20230222010230-f7c08e33a45d
|
||||
k8s.io/apimachinery v0.0.0-20230221210005-6f5782f4e5f2
|
||||
k8s.io/client-go v0.0.0-20230221210539-269abfd8b0cf
|
||||
k8s.io/client-go v0.0.0-20230222010551-1ea719588ec9
|
||||
k8s.io/component-base v0.0.0-20230215215219-ae9be4dda9da
|
||||
k8s.io/klog/v2 v2.80.1
|
||||
k8s.io/kms v0.0.0-20230222011722-d42d0d0bd8f5
|
||||
|
@ -126,7 +126,7 @@ require (
|
|||
replace (
|
||||
k8s.io/api => k8s.io/api v0.0.0-20230222010230-f7c08e33a45d
|
||||
k8s.io/apimachinery => k8s.io/apimachinery v0.0.0-20230221210005-6f5782f4e5f2
|
||||
k8s.io/client-go => k8s.io/client-go v0.0.0-20230221210539-269abfd8b0cf
|
||||
k8s.io/client-go => k8s.io/client-go v0.0.0-20230222010551-1ea719588ec9
|
||||
k8s.io/component-base => k8s.io/component-base v0.0.0-20230215215219-ae9be4dda9da
|
||||
k8s.io/kms => k8s.io/kms v0.0.0-20230222011722-d42d0d0bd8f5
|
||||
)
|
||||
|
|
4
go.sum
4
go.sum
|
@ -999,8 +999,8 @@ k8s.io/api v0.0.0-20230222010230-f7c08e33a45d h1:+VG9Mm3/5hF68jUHCl6VGvr6EakD/mI
|
|||
k8s.io/api v0.0.0-20230222010230-f7c08e33a45d/go.mod h1:pIoETLNxk7aEZKVxgu2QTu7skpwH4/QaSON6m2ZcWk0=
|
||||
k8s.io/apimachinery v0.0.0-20230221210005-6f5782f4e5f2 h1:y1pNlni0a23IANOXLdjpSprc42f8vxsTlI0Ow3Laj8A=
|
||||
k8s.io/apimachinery v0.0.0-20230221210005-6f5782f4e5f2/go.mod h1:8B/+OdWlScxVvirboh1J5IZSHQrCreQ7fi/5UQntvX0=
|
||||
k8s.io/client-go v0.0.0-20230221210539-269abfd8b0cf h1:hD/xLl8inK2burvysLqZIgrbC1RKz8L9UTquJqwlIlg=
|
||||
k8s.io/client-go v0.0.0-20230221210539-269abfd8b0cf/go.mod h1:tDe5+2lG9LJRumMD2hyzyz6bb6UzV7rnXbHx+BH3lCg=
|
||||
k8s.io/client-go v0.0.0-20230222010551-1ea719588ec9 h1:nAPdPrjOaI56gzUZ12srdKt0f34VDHPRPbzQo30HNBw=
|
||||
k8s.io/client-go v0.0.0-20230222010551-1ea719588ec9/go.mod h1:P5yJZqBJ6++A9bFbiCdHKm5hXb/BprMl/qwwWRphXPY=
|
||||
k8s.io/component-base v0.0.0-20230215215219-ae9be4dda9da h1:tgXu2y67YqUXP4txgy1vMTvOOqpT/kzIxmrtE0SvR8M=
|
||||
k8s.io/component-base v0.0.0-20230215215219-ae9be4dda9da/go.mod h1:GgrhCRrPLmN9lWoh+m52a6iHKG3zx8KJyclgqPgbFDQ=
|
||||
k8s.io/klog/v2 v2.80.1 h1:atnLQ121W371wYYFawwYx1aEY2eUfs4l3J72wtgAwV4=
|
||||
|
|
|
@ -682,12 +682,13 @@ func TestPriorityAndFairnessWithPanicRecoveryAndTimeoutFilter(t *testing.T) {
|
|||
stopCh := make(chan struct{})
|
||||
controller, controllerCompletedCh := startAPFController(t, stopCh, apfConfiguration, serverConcurrency, requestTimeout/4, plName, plConcurrency)
|
||||
|
||||
headerMatcher := headerMatcher{}
|
||||
var executed bool
|
||||
// we will raise a panic for the first request.
|
||||
firstRequestPathPanic := "/request/panic-as-designed"
|
||||
requestHandler := http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
|
||||
executed = true
|
||||
expectMatchingAPFHeaders(t, w, fsName, plName)
|
||||
headerMatcher.inspect(w, fsName, plName)
|
||||
|
||||
if r.URL.Path == firstRequestPathPanic {
|
||||
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)
|
||||
}
|
||||
|
||||
for _, err := range headerMatcher.errors() {
|
||||
t.Errorf("Expected APF headers to match, but got: %v", err)
|
||||
}
|
||||
|
||||
close(stopCh)
|
||||
t.Log("Waiting for the controller to shutdown")
|
||||
|
||||
|
@ -747,12 +752,13 @@ func TestPriorityAndFairnessWithPanicRecoveryAndTimeoutFilter(t *testing.T) {
|
|||
stopCh := make(chan struct{})
|
||||
controller, controllerCompletedCh := startAPFController(t, stopCh, apfConfiguration, serverConcurrency, requestTimeout/4, plName, plConcurrency)
|
||||
|
||||
headerMatcher := headerMatcher{}
|
||||
var executed bool
|
||||
rquestTimesOutPath := "/request/time-out-as-designed"
|
||||
reqHandlerCompletedCh, callerRoundTripDoneCh := make(chan struct{}), make(chan struct{})
|
||||
requestHandler := http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
|
||||
executed = true
|
||||
expectMatchingAPFHeaders(t, w, fsName, plName)
|
||||
headerMatcher.inspect(w, fsName, plName)
|
||||
|
||||
if r.URL.Path == rquestTimesOutPath {
|
||||
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)
|
||||
}
|
||||
|
||||
for _, err := range headerMatcher.errors() {
|
||||
t.Errorf("Expected APF headers to match, but got: %v", err)
|
||||
}
|
||||
|
||||
close(stopCh)
|
||||
t.Log("Waiting for the controller to shutdown")
|
||||
|
||||
|
@ -818,11 +828,12 @@ func TestPriorityAndFairnessWithPanicRecoveryAndTimeoutFilter(t *testing.T) {
|
|||
stopCh := make(chan struct{})
|
||||
controller, controllerCompletedCh := startAPFController(t, stopCh, apfConfiguration, serverConcurrency, requestTimeout/4, plName, plConcurrency)
|
||||
|
||||
headerMatcher := headerMatcher{}
|
||||
var innerHandlerWriteErr error
|
||||
reqHandlerCompletedCh, callerRoundTripDoneCh := make(chan struct{}), make(chan struct{})
|
||||
rquestTimesOutPath := "/request/time-out-as-designed"
|
||||
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 {
|
||||
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)
|
||||
}
|
||||
|
||||
for _, err := range headerMatcher.errors() {
|
||||
t.Errorf("Expected APF headers to match, but got: %v", err)
|
||||
}
|
||||
|
||||
close(stopCh)
|
||||
t.Log("Waiting for the controller to shutdown")
|
||||
|
||||
|
@ -891,11 +906,12 @@ func TestPriorityAndFairnessWithPanicRecoveryAndTimeoutFilter(t *testing.T) {
|
|||
stopCh := make(chan struct{})
|
||||
controller, controllerCompletedCh := startAPFController(t, stopCh, apfConfiguration, serverConcurrency, requestTimeout/4, plName, plConcurrency)
|
||||
|
||||
headerMatcher := headerMatcher{}
|
||||
var innerHandlerWriteErr error
|
||||
rquestTimesOutPath := "/request/time-out-as-designed"
|
||||
reqHandlerCompletedCh, callerRoundTripDoneCh := make(chan struct{}), make(chan struct{})
|
||||
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 {
|
||||
defer close(reqHandlerCompletedCh)
|
||||
|
@ -932,6 +948,10 @@ func TestPriorityAndFairnessWithPanicRecoveryAndTimeoutFilter(t *testing.T) {
|
|||
}
|
||||
expectResetStreamError(t, err)
|
||||
|
||||
for _, err := range headerMatcher.errors() {
|
||||
t.Errorf("Expected APF headers to match, but got: %v", err)
|
||||
}
|
||||
|
||||
close(stopCh)
|
||||
t.Log("Waiting for the controller to shutdown")
|
||||
|
||||
|
@ -961,6 +981,7 @@ func TestPriorityAndFairnessWithPanicRecoveryAndTimeoutFilter(t *testing.T) {
|
|||
stopCh := make(chan struct{})
|
||||
controller, controllerCompletedCh := startAPFController(t, stopCh, apfConfiguration, serverConcurrency, requestTimeout/4, plName, plConcurrency)
|
||||
|
||||
headerMatcher := headerMatcher{}
|
||||
var firstRequestInnerHandlerWriteErr error
|
||||
var secondRequestExecuted bool
|
||||
firstRequestTimesOutPath := "/request/first/time-out-as-designed"
|
||||
|
@ -968,7 +989,7 @@ func TestPriorityAndFairnessWithPanicRecoveryAndTimeoutFilter(t *testing.T) {
|
|||
firstReqHandlerCompletedCh, firstReqInProgressCh := make(chan struct{}), make(chan struct{})
|
||||
firstReqRoundTripDoneCh, secondReqRoundTripDoneCh := make(chan struct{}), make(chan struct{})
|
||||
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 {
|
||||
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)
|
||||
}
|
||||
|
||||
for _, err := range headerMatcher.errors() {
|
||||
t.Errorf("Expected APF headers to match, but got: %v", err)
|
||||
}
|
||||
|
||||
close(stopCh)
|
||||
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.
|
||||
func expectMatchingAPFHeaders(t *testing.T, w http.ResponseWriter, expectedFS, expectedPL string) {
|
||||
if w == nil {
|
||||
t.Fatal("expected a non nil HTTP response")
|
||||
func (m *headerMatcher) inspect(w http.ResponseWriter, expectedFS, expectedPL string) {
|
||||
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 {
|
||||
return
|
||||
}
|
||||
|
||||
key := flowcontrol.ResponseHeaderMatchedFlowSchemaUID
|
||||
if value := w.Header().Get(key); expectedFS != value {
|
||||
t.Fatalf("expected HTTP header %s to have value %q, but got: %q", key, expectedFS, value)
|
||||
}
|
||||
m.lock.Lock()
|
||||
defer m.lock.Unlock()
|
||||
m.errsGot = append(m.errsGot, err)
|
||||
}
|
||||
|
||||
key = flowcontrol.ResponseHeaderMatchedPriorityLevelConfigurationUID
|
||||
if value := w.Header().Get(key); expectedPL != value {
|
||||
t.Fatalf("expected HTTP header %s to have value %q, but got %q", key, expectedPL, value)
|
||||
}
|
||||
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
|
||||
|
|
Loading…
Reference in New Issue