From 7206b34b761df27262acc26352fdb7276e8e6f32 Mon Sep 17 00:00:00 2001 From: Tim Ramlot <42113979+inteon@users.noreply.github.com> Date: Tue, 28 Nov 2023 12:41:55 +0100 Subject: [PATCH] added tests to prevent future regressions Signed-off-by: Tim Ramlot <42113979+inteon@users.noreply.github.com> --- pkg/webhook/admission/http_test.go | 54 +++++++++++++++++++++++++ pkg/webhook/authentication/http_test.go | 54 +++++++++++++++++++++++++ 2 files changed, 108 insertions(+) diff --git a/pkg/webhook/admission/http_test.go b/pkg/webhook/admission/http_test.go index be10aea459..ba0c253a73 100644 --- a/pkg/webhook/admission/http_test.go +++ b/pkg/webhook/admission/http_test.go @@ -19,6 +19,7 @@ package admission import ( "bytes" "context" + "crypto/rand" "fmt" "io" "net/http" @@ -84,6 +85,32 @@ var _ = Describe("Admission Webhooks", func() { Expect(respRecorder.Body.String()).To(Equal(expected)) }) + It("should error when given a NoBody", func() { + req := &http.Request{ + Header: http.Header{"Content-Type": []string{"application/json"}}, + Method: http.MethodPost, + Body: http.NoBody, + } + + expected := `{"response":{"uid":"","allowed":false,"status":{"metadata":{},"message":"request body is empty","code":400}}} +` + webhook.ServeHTTP(respRecorder, req) + Expect(respRecorder.Body.String()).To(Equal(expected)) + }) + + It("should error when given an infinite body", func() { + req := &http.Request{ + Header: http.Header{"Content-Type": []string{"application/json"}}, + Method: http.MethodPost, + Body: nopCloser{Reader: rand.Reader}, + } + + expected := `{"response":{"uid":"","allowed":false,"status":{"metadata":{},"message":"request entity is too large; limit is 3145728 bytes","code":400}}} +` + webhook.ServeHTTP(respRecorder, req) + Expect(respRecorder.Body.String()).To(Equal(expected)) + }) + It("should return the response given by the handler with version defaulted to v1", func() { req := &http.Request{ Header: http.Header{"Content-Type": []string{"application/json"}}, @@ -198,6 +225,33 @@ var _ = Describe("Admission Webhooks", func() { return respRecorder.Body.Len() }, time.Second*3).Should(Equal(0)) }) + + It("should handle crashes", func() { + req := &http.Request{ + Header: http.Header{"Content-Type": []string{"application/json"}}, + Method: http.MethodPost, + Body: nopCloser{Reader: bytes.NewBufferString(`{"spec":{"token":"foobar"}}`)}, + } + webhook := &Webhook{ + Handler: &fakeHandler{ + fn: func(ctx context.Context, req Request) Response { + panic("boom") + }, + }, + } + + expected := `internal server error +` + (func() { + defer func() { + if r := recover(); r != nil { + Expect(r).To(Equal("boom")) + } + }() + webhook.ServeHTTP(respRecorder, req) + })() + Expect(respRecorder.Body.String()).To(Equal(expected)) + }) }) }) diff --git a/pkg/webhook/authentication/http_test.go b/pkg/webhook/authentication/http_test.go index 86bd5d0153..b783d181e5 100644 --- a/pkg/webhook/authentication/http_test.go +++ b/pkg/webhook/authentication/http_test.go @@ -19,6 +19,7 @@ package authentication import ( "bytes" "context" + "crypto/rand" "fmt" "io" "net/http" @@ -94,6 +95,32 @@ var _ = Describe("Authentication Webhooks", func() { Expect(respRecorder.Body.String()).To(Equal(expected)) }) + It("should error when given a NoBody", func() { + req := &http.Request{ + Header: http.Header{"Content-Type": []string{"application/json"}}, + Method: http.MethodPost, + Body: http.NoBody, + } + + expected := `{"metadata":{"creationTimestamp":null},"spec":{},"status":{"user":{},"error":"request body is empty"}} +` + webhook.ServeHTTP(respRecorder, req) + Expect(respRecorder.Body.String()).To(Equal(expected)) + }) + + It("should error when given an infinite body", func() { + req := &http.Request{ + Header: http.Header{"Content-Type": []string{"application/json"}}, + Method: http.MethodPost, + Body: nopCloser{Reader: rand.Reader}, + } + + expected := `{"metadata":{"creationTimestamp":null},"spec":{},"status":{"user":{},"error":"request entity is too large; limit is 3145728 bytes"}} +` + webhook.ServeHTTP(respRecorder, req) + Expect(respRecorder.Body.String()).To(Equal(expected)) + }) + It("should return the response given by the handler with version defaulted to v1", func() { req := &http.Request{ Header: http.Header{"Content-Type": []string{"application/json"}}, @@ -181,6 +208,33 @@ var _ = Describe("Authentication Webhooks", func() { webhook.ServeHTTP(respRecorder, req.WithContext(ctx)) Expect(respRecorder.Body.String()).To(Equal(expected)) }) + + It("should handle crashes", func() { + req := &http.Request{ + Header: http.Header{"Content-Type": []string{"application/json"}}, + Method: http.MethodPost, + Body: nopCloser{Reader: bytes.NewBufferString(`{"spec":{"token":"foobar"}}`)}, + } + webhook := &Webhook{ + Handler: &fakeHandler{ + fn: func(ctx context.Context, req Request) Response { + panic("boom") + }, + }, + } + + expected := `internal server error +` + (func() { + defer func() { + if r := recover(); r != nil { + Expect(r).To(Equal("boom")) + } + }() + webhook.ServeHTTP(respRecorder, req) + })() + Expect(respRecorder.Body.String()).To(Equal(expected)) + }) }) })