Skip to content

Commit d4569f8

Browse files
authored
Merge pull request #276 from justinsb/record_watch_requests
httprecorder: recognize and stream watch responses
2 parents bd86aa5 + f1fe98b commit d4569f8

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)