Skip to content

Commit f1fe98b

Browse files
committed
httprecorder: recognize and stream watch responses
Otherwise we were trying to buffer them entirely, which wasn't working well. Note that we now also capture the second reconcile, triggered by the status update.
1 parent 46568ad commit f1fe98b

File tree

5 files changed

+200
-9
lines changed

5 files changed

+200
-9
lines changed

pkg/patterns/declarative/pkg/applier/applylib_test.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -120,7 +120,7 @@ var _ mockkubeapiserver.BeforeHTTPOperation = &logKubeRequestsHook{}
120120

121121
func (h *logKubeRequestsHook) BeforeHTTPOperation(op *mockkubeapiserver.HTTPOperation) {
122122
req := op.Request
123-
entry := httprecorder.LogEntry{}
123+
entry := &httprecorder.LogEntry{}
124124
entry.Request = httprecorder.Request{
125125
Method: req.Method,
126126
URL: req.URL.String(),

pkg/test/httprecorder/http_recorder.go

Lines changed: 15 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -19,7 +19,7 @@ func NewRecorder(inner http.RoundTripper, log *RequestLog) *HTTPRecorder {
1919
}
2020

2121
func (m *HTTPRecorder) RoundTrip(request *http.Request) (*http.Response, error) {
22-
entry := LogEntry{}
22+
entry := &LogEntry{}
2323
entry.Request = Request{
2424
Method: request.Method,
2525
URL: request.URL.String(),
@@ -35,6 +35,14 @@ func (m *HTTPRecorder) RoundTrip(request *http.Request) (*http.Response, error)
3535
request.Body = io.NopCloser(bytes.NewReader(requestBody))
3636
}
3737

38+
streaming := false
39+
if request.URL.Query().Get("watch") == "true" {
40+
streaming = true
41+
}
42+
43+
// We log the request here, because otherwise we miss long-running requests (watches)
44+
m.log.Entries = append(m.log.Entries, entry)
45+
3846
response, err := m.inner.RoundTrip(request)
3947

4048
if response != nil {
@@ -53,18 +61,18 @@ func (m *HTTPRecorder) RoundTrip(request *http.Request) (*http.Response, error)
5361
}
5462
}
5563

56-
if response.Body != nil {
57-
requestBody, err := io.ReadAll(response.Body)
64+
if streaming {
65+
entry.Response.Body = "<streaming response not included>"
66+
} else if response.Body != nil {
67+
responseBody, err := io.ReadAll(response.Body)
5868
if err != nil {
5969
entry.Response.Body = fmt.Sprintf("<error reading response:%v>", err)
6070
} else {
61-
entry.Response.Body = string(requestBody)
62-
response.Body = io.NopCloser(bytes.NewReader(requestBody))
71+
entry.Response.Body = string(responseBody)
72+
response.Body = io.NopCloser(bytes.NewReader(responseBody))
6373
}
6474
}
6575
}
6676

67-
m.log.Entries = append(m.log.Entries, entry)
68-
6977
return response, err
7078
}

pkg/test/httprecorder/request_log.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -81,7 +81,7 @@ func (r *Response) FormatHTTP() string {
8181
}
8282

8383
type RequestLog struct {
84-
Entries []LogEntry
84+
Entries []*LogEntry
8585
}
8686

8787
func (l *RequestLog) FormatHTTP() string {

pkg/test/testreconciler/simpletest/testdata/reconcile/direct/create/expected-http.yaml

Lines changed: 67 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,18 @@ Date: (removed)
2424

2525
---
2626

27+
GET http://kube-apiserver/apis/addons.example.org/v1alpha1/simpletests?allowWatchBookmarks=true&resourceVersion=3&timeoutSeconds=<replaced>&watch=true
28+
Accept: application/json, */*
29+
30+
200 OK
31+
Cache-Control: no-cache, private
32+
Content-Type: application/json
33+
Date: (removed)
34+
35+
<streaming response not included>
36+
37+
---
38+
2739
GET http://kube-apiserver/api/v1?timeout=32s
2840
Accept: application/json, */*
2941

@@ -95,13 +107,68 @@ Date: (removed)
95107

96108
---
97109

110+
GET http://kube-apiserver/api/v1/configmaps?allowWatchBookmarks=true&labelSelector=addons.example.org%2Fsimpletest%3Dsimple1&watch=true
111+
Accept: application/json
112+
113+
200 OK
114+
Cache-Control: no-cache, private
115+
Content-Type: application/json
116+
Date: (removed)
117+
118+
<streaming response not included>
119+
120+
---
121+
98122
PUT http://kube-apiserver/apis/addons.example.org/v1alpha1/namespaces/ns1/simpletests/simple1/status
99123
Accept: application/json, */*
100124
Content-Type: application/json
101125

102126
{"kind":"SimpleTest","apiVersion":"addons.example.org/v1alpha1","metadata":{"name":"simple1","namespace":"ns1","uid":"00000000-0000-0000-0000-000000000002","resourceVersion":"2","creationTimestamp":"2022-01-01T00:00:01Z"},"spec":{"channel":"stable"},"status":{"healthy":true}}
103127

104128

129+
200 OK
130+
Cache-Control: no-cache, private
131+
Content-Length: 276
132+
Content-Type: application/json
133+
Date: (removed)
134+
135+
{"apiVersion":"addons.example.org/v1alpha1","kind":"SimpleTest","metadata":{"creationTimestamp":"2022-01-01T00:00:01Z","name":"simple1","namespace":"ns1","resourceVersion":"4","uid":"00000000-0000-0000-0000-000000000002"},"spec":{"channel":"stable"},"status":{"healthy":true}}
136+
137+
---
138+
139+
GET http://kube-apiserver/api/v1/namespaces/ns1/configmaps/foo
140+
Accept: application/json
141+
142+
200 OK
143+
Cache-Control: no-cache, private
144+
Content-Length: 1025
145+
Content-Type: application/json
146+
Date: (removed)
147+
148+
{"apiVersion":"v1","data":{"k1":"v1"},"kind":"ConfigMap","metadata":{"annotations":{"kubectl.kubernetes.io/last-applied-configuration":"{\"apiVersion\":\"v1\",\"data\":{\"k1\":\"v1\"},\"kind\":\"ConfigMap\",\"metadata\":{\"annotations\":{},\"labels\":{\"addons.example.org/simpletest\":\"simple1\",\"example-app\":\"simpletest\",\"l1\":\"v1\"},\"name\":\"foo\",\"namespace\":\"ns1\",\"ownerReferences\":[{\"apiVersion\":\"addons.example.org/v1alpha1\",\"blockOwnerDeletion\":true,\"controller\":true,\"kind\":\"SimpleTest\",\"name\":\"simple1\",\"uid\":\"00000000-0000-0000-0000-000000000002\"}]}}\n"},"creationTimestamp":"2022-01-01T00:00:02Z","labels":{"addons.example.org/simpletest":"simple1","example-app":"simpletest","l1":"v1"},"name":"foo","namespace":"ns1","ownerReferences":[{"apiVersion":"addons.example.org/v1alpha1","blockOwnerDeletion":true,"controller":true,"kind":"SimpleTest","name":"simple1","uid":"00000000-0000-0000-0000-000000000002"}],"resourceVersion":"3","uid":"00000000-0000-0000-0000-000000000003"}}
149+
150+
---
151+
152+
GET http://kube-apiserver/api/v1/namespaces/ns1/configmaps/foo
153+
Accept: application/json
154+
155+
200 OK
156+
Cache-Control: no-cache, private
157+
Content-Length: 1025
158+
Content-Type: application/json
159+
Date: (removed)
160+
161+
{"apiVersion":"v1","data":{"k1":"v1"},"kind":"ConfigMap","metadata":{"annotations":{"kubectl.kubernetes.io/last-applied-configuration":"{\"apiVersion\":\"v1\",\"data\":{\"k1\":\"v1\"},\"kind\":\"ConfigMap\",\"metadata\":{\"annotations\":{},\"labels\":{\"addons.example.org/simpletest\":\"simple1\",\"example-app\":\"simpletest\",\"l1\":\"v1\"},\"name\":\"foo\",\"namespace\":\"ns1\",\"ownerReferences\":[{\"apiVersion\":\"addons.example.org/v1alpha1\",\"blockOwnerDeletion\":true,\"controller\":true,\"kind\":\"SimpleTest\",\"name\":\"simple1\",\"uid\":\"00000000-0000-0000-0000-000000000002\"}]}}\n"},"creationTimestamp":"2022-01-01T00:00:02Z","labels":{"addons.example.org/simpletest":"simple1","example-app":"simpletest","l1":"v1"},"name":"foo","namespace":"ns1","ownerReferences":[{"apiVersion":"addons.example.org/v1alpha1","blockOwnerDeletion":true,"controller":true,"kind":"SimpleTest","name":"simple1","uid":"00000000-0000-0000-0000-000000000002"}],"resourceVersion":"3","uid":"00000000-0000-0000-0000-000000000003"}}
162+
163+
---
164+
165+
PUT http://kube-apiserver/apis/addons.example.org/v1alpha1/namespaces/ns1/simpletests/simple1/status
166+
Accept: application/json, */*
167+
Content-Type: application/json
168+
169+
{"kind":"SimpleTest","apiVersion":"addons.example.org/v1alpha1","metadata":{"name":"simple1","namespace":"ns1","uid":"00000000-0000-0000-0000-000000000002","resourceVersion":"4","creationTimestamp":"2022-01-01T00:00:01Z"},"spec":{"channel":"stable"},"status":{"healthy":true}}
170+
171+
105172
200 OK
106173
Cache-Control: no-cache, private
107174
Content-Length: 276

pkg/test/testreconciler/simpletest/testdata/reconcile/ssa/create/expected-http.yaml

Lines changed: 116 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,18 @@ Date: (removed)
2424

2525
---
2626

27+
GET http://kube-apiserver/apis/addons.example.org/v1alpha1/simpletests?allowWatchBookmarks=true&resourceVersion=3&timeoutSeconds=<replaced>&watch=true
28+
Accept: application/json, */*
29+
30+
200 OK
31+
Cache-Control: no-cache, private
32+
Content-Type: application/json
33+
Date: (removed)
34+
35+
<streaming response not included>
36+
37+
---
38+
2739
GET http://kube-apiserver/api/v1?timeout=32s
2840
Accept: application/json, */*
2941

@@ -74,6 +86,110 @@ Content-Type: application/json
7486
{"kind":"SimpleTest","apiVersion":"addons.example.org/v1alpha1","metadata":{"name":"simple1","namespace":"ns1","uid":"00000000-0000-0000-0000-000000000002","resourceVersion":"2","creationTimestamp":"2022-01-01T00:00:01Z"},"spec":{"channel":"stable"},"status":{"healthy":true}}
7587

7688

89+
200 OK
90+
Cache-Control: no-cache, private
91+
Content-Length: 276
92+
Content-Type: application/json
93+
Date: (removed)
94+
95+
{"apiVersion":"addons.example.org/v1alpha1","kind":"SimpleTest","metadata":{"creationTimestamp":"2022-01-01T00:00:01Z","name":"simple1","namespace":"ns1","resourceVersion":"4","uid":"00000000-0000-0000-0000-000000000002"},"spec":{"channel":"stable"},"status":{"healthy":true}}
96+
97+
---
98+
99+
GET http://kube-apiserver/api/v1/configmaps?allowWatchBookmarks=true&labelSelector=addons.example.org%2Fsimpletest%3Dsimple1&watch=true
100+
Accept: application/json
101+
102+
200 OK
103+
Cache-Control: no-cache, private
104+
Content-Type: application/json
105+
Date: (removed)
106+
107+
<streaming response not included>
108+
109+
---
110+
111+
GET http://kube-apiserver/api/v1/namespaces/ns1/configmaps/foo
112+
Accept: application/json
113+
114+
200 OK
115+
Cache-Control: no-cache, private
116+
Content-Length: 492
117+
Content-Type: application/json
118+
Date: (removed)
119+
120+
{"apiVersion":"v1","data":{"k1":"v1"},"kind":"ConfigMap","metadata":{"creationTimestamp":"2022-01-01T00:00:02Z","labels":{"addons.example.org/simpletest":"simple1","example-app":"simpletest","l1":"v1"},"name":"foo","namespace":"ns1","ownerReferences":[{"apiVersion":"addons.example.org/v1alpha1","blockOwnerDeletion":true,"controller":true,"kind":"SimpleTest","name":"simple1","uid":"00000000-0000-0000-0000-000000000002"}],"resourceVersion":"3","uid":"00000000-0000-0000-0000-000000000003"}}
121+
122+
---
123+
124+
PATCH http://kube-apiserver/api/v1/namespaces/ns1/configmaps/foo?fieldManager=kdp-test&force=true
125+
Accept: application/json
126+
Content-Type: application/apply-patch+yaml
127+
128+
{"apiVersion":"v1","data":{"k1":"v1"},"kind":"ConfigMap","metadata":{"labels":{"addons.example.org/simpletest":"simple1","example-app":"simpletest","l1":"v1"},"name":"foo","namespace":"ns1","ownerReferences":[{"apiVersion":"addons.example.org/v1alpha1","blockOwnerDeletion":true,"controller":true,"kind":"SimpleTest","name":"simple1","uid":"00000000-0000-0000-0000-000000000002"}]}}
129+
130+
200 OK
131+
Cache-Control: no-cache, private
132+
Content-Length: 492
133+
Content-Type: application/json
134+
Date: (removed)
135+
136+
{"apiVersion":"v1","data":{"k1":"v1"},"kind":"ConfigMap","metadata":{"creationTimestamp":"2022-01-01T00:00:02Z","labels":{"addons.example.org/simpletest":"simple1","example-app":"simpletest","l1":"v1"},"name":"foo","namespace":"ns1","ownerReferences":[{"apiVersion":"addons.example.org/v1alpha1","blockOwnerDeletion":true,"controller":true,"kind":"SimpleTest","name":"simple1","uid":"00000000-0000-0000-0000-000000000002"}],"resourceVersion":"3","uid":"00000000-0000-0000-0000-000000000003"}}
137+
138+
---
139+
140+
PUT http://kube-apiserver/apis/addons.example.org/v1alpha1/namespaces/ns1/simpletests/simple1/status
141+
Accept: application/json, */*
142+
Content-Type: application/json
143+
144+
{"kind":"SimpleTest","apiVersion":"addons.example.org/v1alpha1","metadata":{"name":"simple1","namespace":"ns1","uid":"00000000-0000-0000-0000-000000000002","resourceVersion":"4","creationTimestamp":"2022-01-01T00:00:01Z"},"spec":{"channel":"stable"},"status":{"healthy":true}}
145+
146+
147+
200 OK
148+
Cache-Control: no-cache, private
149+
Content-Length: 276
150+
Content-Type: application/json
151+
Date: (removed)
152+
153+
{"apiVersion":"addons.example.org/v1alpha1","kind":"SimpleTest","metadata":{"creationTimestamp":"2022-01-01T00:00:01Z","name":"simple1","namespace":"ns1","resourceVersion":"4","uid":"00000000-0000-0000-0000-000000000002"},"spec":{"channel":"stable"},"status":{"healthy":true}}
154+
155+
---
156+
157+
GET http://kube-apiserver/api/v1/namespaces/ns1/configmaps/foo
158+
Accept: application/json
159+
160+
200 OK
161+
Cache-Control: no-cache, private
162+
Content-Length: 492
163+
Content-Type: application/json
164+
Date: (removed)
165+
166+
{"apiVersion":"v1","data":{"k1":"v1"},"kind":"ConfigMap","metadata":{"creationTimestamp":"2022-01-01T00:00:02Z","labels":{"addons.example.org/simpletest":"simple1","example-app":"simpletest","l1":"v1"},"name":"foo","namespace":"ns1","ownerReferences":[{"apiVersion":"addons.example.org/v1alpha1","blockOwnerDeletion":true,"controller":true,"kind":"SimpleTest","name":"simple1","uid":"00000000-0000-0000-0000-000000000002"}],"resourceVersion":"3","uid":"00000000-0000-0000-0000-000000000003"}}
167+
168+
---
169+
170+
PATCH http://kube-apiserver/api/v1/namespaces/ns1/configmaps/foo?fieldManager=kdp-test&force=true
171+
Accept: application/json
172+
Content-Type: application/apply-patch+yaml
173+
174+
{"apiVersion":"v1","data":{"k1":"v1"},"kind":"ConfigMap","metadata":{"labels":{"addons.example.org/simpletest":"simple1","example-app":"simpletest","l1":"v1"},"name":"foo","namespace":"ns1","ownerReferences":[{"apiVersion":"addons.example.org/v1alpha1","blockOwnerDeletion":true,"controller":true,"kind":"SimpleTest","name":"simple1","uid":"00000000-0000-0000-0000-000000000002"}]}}
175+
176+
200 OK
177+
Cache-Control: no-cache, private
178+
Content-Length: 492
179+
Content-Type: application/json
180+
Date: (removed)
181+
182+
{"apiVersion":"v1","data":{"k1":"v1"},"kind":"ConfigMap","metadata":{"creationTimestamp":"2022-01-01T00:00:02Z","labels":{"addons.example.org/simpletest":"simple1","example-app":"simpletest","l1":"v1"},"name":"foo","namespace":"ns1","ownerReferences":[{"apiVersion":"addons.example.org/v1alpha1","blockOwnerDeletion":true,"controller":true,"kind":"SimpleTest","name":"simple1","uid":"00000000-0000-0000-0000-000000000002"}],"resourceVersion":"3","uid":"00000000-0000-0000-0000-000000000003"}}
183+
184+
---
185+
186+
PUT http://kube-apiserver/apis/addons.example.org/v1alpha1/namespaces/ns1/simpletests/simple1/status
187+
Accept: application/json, */*
188+
Content-Type: application/json
189+
190+
{"kind":"SimpleTest","apiVersion":"addons.example.org/v1alpha1","metadata":{"name":"simple1","namespace":"ns1","uid":"00000000-0000-0000-0000-000000000002","resourceVersion":"4","creationTimestamp":"2022-01-01T00:00:01Z"},"spec":{"channel":"stable"},"status":{"healthy":true}}
191+
192+
77193
200 OK
78194
Cache-Control: no-cache, private
79195
Content-Length: 276

0 commit comments

Comments
 (0)