...
1
16
17 package apimachinery
18
19 import (
20 "context"
21 "io"
22 "net/http"
23 "strings"
24
25 "github.com/onsi/ginkgo/v2"
26 "k8s.io/client-go/rest"
27 "k8s.io/kubernetes/test/e2e/framework"
28 admissionapi "k8s.io/pod-security-admission/api"
29 )
30
31 const (
32 invalidTimeoutMessageExpected = "invalid timeout specified in the request URL"
33 )
34
35 var _ = SIGDescribe("Server request timeout", func() {
36 f := framework.NewDefaultFramework("request-timeout")
37 f.NamespacePodSecurityLevel = admissionapi.LevelPrivileged
38
39 ginkgo.It("should return HTTP status code 400 if the user specifies an invalid timeout in the request URL", func(ctx context.Context) {
40 rt := getRoundTripper(f)
41 req := newRequest(f, "invalid")
42
43 response, err := rt.RoundTrip(req)
44 framework.ExpectNoError(err)
45 defer response.Body.Close()
46
47 if response.StatusCode != http.StatusBadRequest {
48 framework.Failf("expected HTTP status code: %d, but got: %d", http.StatusBadRequest, response.StatusCode)
49 }
50
51 messageGot := readBody(response)
52 if !strings.Contains(messageGot, invalidTimeoutMessageExpected) {
53 framework.Failf("expected HTTP status message to contain: %s, but got: %s", invalidTimeoutMessageExpected, messageGot)
54 }
55 })
56
57 ginkgo.It("the request should be served with a default timeout if the specified timeout in the request URL exceeds maximum allowed", func(ctx context.Context) {
58 rt := getRoundTripper(f)
59
60 req := newRequest(f, "3m")
61
62 response, err := rt.RoundTrip(req)
63 framework.ExpectNoError(err)
64 defer response.Body.Close()
65
66 if response.StatusCode != http.StatusOK {
67 framework.Failf("expected HTTP status code: %d, but got: %d", http.StatusOK, response.StatusCode)
68 }
69 })
70
71 ginkgo.It("default timeout should be used if the specified timeout in the request URL is 0s", func(ctx context.Context) {
72 rt := getRoundTripper(f)
73 req := newRequest(f, "0s")
74
75 response, err := rt.RoundTrip(req)
76 framework.ExpectNoError(err)
77 defer response.Body.Close()
78
79 if response.StatusCode != http.StatusOK {
80 framework.Failf("expected HTTP status code: %d, but got: %d", http.StatusOK, response.StatusCode)
81 }
82 })
83 })
84
85 func getRoundTripper(f *framework.Framework) http.RoundTripper {
86 config := rest.CopyConfig(f.ClientConfig())
87
88
89 config.Timeout = 0
90
91 roundTripper, err := rest.TransportFor(config)
92 framework.ExpectNoError(err)
93
94 return roundTripper
95 }
96
97 func newRequest(f *framework.Framework, timeout string) *http.Request {
98 req, err := http.NewRequest(http.MethodGet, f.ClientSet.CoreV1().RESTClient().Get().
99 Param("timeout", timeout).AbsPath("version").URL().String(), nil)
100 framework.ExpectNoError(err)
101
102 return req
103 }
104
105 func readBody(response *http.Response) string {
106 raw, err := io.ReadAll(response.Body)
107 framework.ExpectNoError(err)
108
109 return string(raw)
110 }
111
View as plain text