From 933707183573484b597b5be59bf39f0aa1187cb0 Mon Sep 17 00:00:00 2001 From: Richard Marmorstein Date: Wed, 6 Dec 2023 15:27:49 -0800 Subject: [PATCH 1/9] Usage infrastructure --- params.go | 8 +++ stripe.go | 134 +++++++++++++++++++++++++++++++++++++------------ stripe_test.go | 33 ++---------- 3 files changed, 112 insertions(+), 63 deletions(-) diff --git a/params.go b/params.go index c958b3167c..8dc45e0dd6 100644 --- a/params.go +++ b/params.go @@ -202,6 +202,8 @@ type Params struct { // account instead of under the account of the owner of the configured // Stripe key. StripeAccount *string `form:"-"` // Passed as header + + usage []string `form:"-"` // Tracked behaviors } // AddExpand on the Params embedded struct is deprecated. @@ -210,6 +212,12 @@ func (p *Params) AddExpand(f string) { p.Expand = append(p.Expand, &f) } +// SetUsage sets the usage field on the Params struct. +// Unstable: for internal stripe-go usage only. +func (p *Params) SetUsage(usage []string) { + p.usage = usage +} + // AddExtra adds a new arbitrary key-value pair to the request data func (p *Params) AddExtra(key, value string) { if p.Extra == nil { diff --git a/stripe.go b/stripe.go index e74503e3ff..0dacfe95ee 100644 --- a/stripe.go +++ b/stripe.go @@ -108,6 +108,8 @@ type APIResponse struct { // StatusCode is a status code as integer. e.g. 200 StatusCode int + + duration *time.Duration } // StreamingAPIResponse encapsulates some common features of a response from the @@ -122,9 +124,10 @@ type StreamingAPIResponse struct { RequestID string Status string StatusCode int + duration *time.Duration } -func newAPIResponse(res *http.Response, resBody []byte) *APIResponse { +func newAPIResponse(res *http.Response, resBody []byte, requestDuration *time.Duration) *APIResponse { return &APIResponse{ Header: res.Header, IdempotencyKey: res.Header.Get("Idempotency-Key"), @@ -132,10 +135,11 @@ func newAPIResponse(res *http.Response, resBody []byte) *APIResponse { RequestID: res.Header.Get("Request-Id"), Status: res.Status, StatusCode: res.StatusCode, + duration: requestDuration, } } -func newStreamingAPIResponse(res *http.Response, body io.ReadCloser) *StreamingAPIResponse { +func newStreamingAPIResponse(res *http.Response, body io.ReadCloser, requestDuration *time.Duration) *StreamingAPIResponse { return &StreamingAPIResponse{ Header: res.Header, IdempotencyKey: res.Header.Get("Idempotency-Key"), @@ -143,6 +147,7 @@ func newStreamingAPIResponse(res *http.Response, body io.ReadCloser) *StreamingA RequestID: res.Header.Get("Request-Id"), Status: res.Status, StatusCode: res.StatusCode, + duration: requestDuration, } } @@ -275,6 +280,34 @@ type BackendImplementation struct { requestMetricsBuffer chan requestMetrics } +type unmarshalTargeter interface { + GetUnmarshalTarget() interface{} +} + +type lastResponseSetterWrapper struct { + f func(*APIResponse) + unmarshalTarget LastResponseSetter +} + +func (l *lastResponseSetterWrapper) SetLastResponse(response *APIResponse) { + l.f(response) +} +func (l *lastResponseSetterWrapper) GetUnmarshalTarget() interface{} { + return l.unmarshalTarget +} + +type streamingLastResponseSetterWrapper struct { + f func(*StreamingAPIResponse) + unmarshalTarget StreamingLastResponseSetter +} + +func (l *streamingLastResponseSetterWrapper) SetLastResponse(response *StreamingAPIResponse) { + l.f(response) +} +func (l *streamingLastResponseSetterWrapper) GetUnmarshalTarget() interface{} { + return l.unmarshalTarget +} + func extractParams(params ParamsContainer) (*form.Values, *Params, error) { var formValues *form.Values var commonParams *Params @@ -346,7 +379,19 @@ func (s *BackendImplementation) CallStreaming(method, path, key string, params P return err } - if err := s.DoStreaming(req, bodyBuffer, v); err != nil { + responseSetter := streamingLastResponseSetterWrapper{ + func(response *StreamingAPIResponse) { + var usage []string + if commonParams != nil { + usage = commonParams.usage + } + s.maybeEnqueueTelemetryMetrics(response.RequestID, response.duration, usage) + v.SetLastResponse(response) + }, + v, + } + + if err := s.DoStreaming(req, bodyBuffer, &responseSetter); err != nil { return err } @@ -388,7 +433,19 @@ func (s *BackendImplementation) CallRaw(method, path, key string, form *form.Val return err } - if err := s.Do(req, bodyBuffer, v); err != nil { + responseSetter := lastResponseSetterWrapper{ + f: func(response *APIResponse) { + var usage []string + if params != nil { + usage = params.usage + } + s.maybeEnqueueTelemetryMetrics(response.RequestID, response.duration, usage) + v.SetLastResponse(response) + }, + unmarshalTarget: v, + } + + if err := s.Do(req, bodyBuffer, &responseSetter); err != nil { return err } @@ -468,22 +525,26 @@ func (s *BackendImplementation) maybeSetTelemetryHeader(req *http.Request) { } } -func (s *BackendImplementation) maybeEnqueueTelemetryMetrics(res *http.Response, requestDuration time.Duration) { - if s.enableTelemetry && res != nil { - reqID := res.Header.Get("Request-Id") - if len(reqID) > 0 { - metrics := requestMetrics{ - RequestDurationMS: int(requestDuration / time.Millisecond), - RequestID: reqID, - } - - // If the metrics buffer is full, discard the new metrics. Otherwise, add - // them to the buffer. - select { - case s.requestMetricsBuffer <- metrics: - default: - } - } +func (s *BackendImplementation) maybeEnqueueTelemetryMetrics(requestID string, requestDuration *time.Duration, usage []string) { + if !s.enableTelemetry || requestID == "" { + return + } + if requestDuration == nil && (usage == nil || len(usage) == 0) { + return + } + metrics := requestMetrics{ + RequestID: requestID, + } + if requestDuration != nil { + requestDurationMS := int(*requestDuration / time.Millisecond) + metrics.RequestDurationMS = &requestDurationMS + } + if usage != nil && len(usage) > 0 { + metrics.Usage = usage + } + select { + case s.requestMetricsBuffer <- metrics: + default: } } @@ -541,7 +602,7 @@ func (s *BackendImplementation) requestWithRetriesAndTelemetry( req *http.Request, body *bytes.Buffer, handleResponse func(*http.Response, error) (interface{}, error), -) (*http.Response, interface{}, error) { +) (*http.Response, interface{}, *time.Duration, error) { s.LeveledLogger.Infof("Requesting %v %v%v", req.Method, req.URL.Host, req.URL.Path) s.maybeSetTelemetryHeader(req) var resp *http.Response @@ -577,13 +638,11 @@ func (s *BackendImplementation) requestWithRetriesAndTelemetry( time.Sleep(sleepDuration) } - s.maybeEnqueueTelemetryMetrics(resp, requestDuration) - if err != nil { - return nil, nil, err + return nil, nil, nil, err } - return resp, result, nil + return resp, result, &requestDuration, nil } func (s *BackendImplementation) logError(statusCode int, err error) { @@ -645,11 +704,11 @@ func (s *BackendImplementation) DoStreaming(req *http.Request, body *bytes.Buffe return res.Body, err } - resp, result, err := s.requestWithRetriesAndTelemetry(req, body, handleResponse) + resp, result, requestDuration, err := s.requestWithRetriesAndTelemetry(req, body, handleResponse) if err != nil { return err } - v.SetLastResponse(newStreamingAPIResponse(resp, result.(io.ReadCloser))) + v.SetLastResponse(newStreamingAPIResponse(resp, result.(io.ReadCloser), requestDuration)) return nil } @@ -675,14 +734,22 @@ func (s *BackendImplementation) Do(req *http.Request, body *bytes.Buffer, v Last return resBody, err } - res, result, err := s.requestWithRetriesAndTelemetry(req, body, handleResponse) + res, result, requestDuration, err := s.requestWithRetriesAndTelemetry(req, body, handleResponse) if err != nil { return err } resBody := result.([]byte) s.LeveledLogger.Debugf("Response: %s", string(resBody)) - err = s.UnmarshalJSONVerbose(res.StatusCode, resBody, v) - v.SetLastResponse(newAPIResponse(res, resBody)) + var unmarshalTarget interface{} + targeter, ok := v.(unmarshalTargeter) + if ok { + unmarshalTarget = targeter.GetUnmarshalTarget() + } else { + unmarshalTarget = v + } + + err = s.UnmarshalJSONVerbose(res.StatusCode, resBody, unmarshalTarget) + v.SetLastResponse(newAPIResponse(res, resBody, requestDuration)) return err } @@ -733,7 +800,7 @@ func (s *BackendImplementation) ResponseToError(res *http.Response, resBody []by } raw.Error.Err = typedError - raw.Error.SetLastResponse(newAPIResponse(res, resBody)) + raw.Error.SetLastResponse(newAPIResponse(res, resBody, nil)) return raw.Error } @@ -1270,8 +1337,9 @@ type stripeClientUserAgent struct { // requestMetrics contains the id and duration of the last request sent type requestMetrics struct { - RequestDurationMS int `json:"request_duration_ms"` - RequestID string `json:"request_id"` + RequestDurationMS *int `json:"request_duration_ms"` + RequestID string `json:"request_id"` + Usage []string `json:"usage"` } // requestTelemetry contains the payload sent in the diff --git a/stripe_test.go b/stripe_test.go index bac6a5ea33..a8e92eb5a3 100644 --- a/stripe_test.go +++ b/stripe_test.go @@ -474,17 +474,8 @@ func TestDo_TelemetryDisabled(t *testing.T) { // _next_ request via the `X-Stripe-Client-Telemetry header`. To test that // metrics aren't being sent, we need to fire off two requests in sequence. for i := 0; i < 2; i++ { - request, err := backend.NewRequest( - http.MethodGet, - "/hello", - "sk_test_123", - "application/x-www-form-urlencoded", - nil, - ) - assert.NoError(t, err) - var response testServerResponse - err = backend.Do(request, nil, &response) + err := backend.Call("get", "/hello", "sk_test_xyz", nil, &response) assert.NoError(t, err) assert.Equal(t, message, response.Message) @@ -561,17 +552,8 @@ func TestDo_TelemetryEnabled(t *testing.T) { ).(*BackendImplementation) for i := 0; i < 2; i++ { - request, err := backend.NewRequest( - http.MethodGet, - "/hello", - "sk_test_123", - "application/x-www-form-urlencoded", - nil, - ) - assert.NoError(t, err) - var response testServerResponse - err = backend.Do(request, nil, &response) + err := backend.Call("get", "/hello", "sk_test_xyz", nil, &response) assert.NoError(t, err) assert.Equal(t, message, response.Message) @@ -623,17 +605,8 @@ func TestDo_TelemetryEnabledNoDataRace(t *testing.T) { for i := 0; i < times; i++ { go func() { - request, err := backend.NewRequest( - http.MethodGet, - "/hello", - "sk_test_123", - "application/x-www-form-urlencoded", - nil, - ) - assert.NoError(t, err) - var response testServerResponse - err = backend.Do(request, nil, &response) + err := backend.Call("get", "/hello", "sk_test_xyz", nil, &response) assert.NoError(t, err) assert.Equal(t, message, response.Message) From 1e3058f47a862e54c34912d0423be3e94a03baa4 Mon Sep 17 00:00:00 2001 From: Richard Marmorstein Date: Wed, 6 Dec 2023 16:27:19 -0800 Subject: [PATCH 2/9] fix --- stripe.go | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/stripe.go b/stripe.go index 0dacfe95ee..4570fa1f55 100644 --- a/stripe.go +++ b/stripe.go @@ -529,7 +529,8 @@ func (s *BackendImplementation) maybeEnqueueTelemetryMetrics(requestID string, r if !s.enableTelemetry || requestID == "" { return } - if requestDuration == nil && (usage == nil || len(usage) == 0) { + // If there's no duration to report and no usage to report, don't bother + if requestDuration == nil && len(usage) == 0 { return } metrics := requestMetrics{ @@ -539,7 +540,7 @@ func (s *BackendImplementation) maybeEnqueueTelemetryMetrics(requestID string, r requestDurationMS := int(*requestDuration / time.Millisecond) metrics.RequestDurationMS = &requestDurationMS } - if usage != nil && len(usage) > 0 { + if len(usage) > 0 { metrics.Usage = usage } select { From 658fcfaad231f3f9779a32c543871a78738bf729 Mon Sep 17 00:00:00 2001 From: Richard Marmorstein Date: Thu, 7 Dec 2023 09:18:15 -0800 Subject: [PATCH 3/9] custom UnmarshalJSON instead of unmarshaltargeter --- stripe.go | 35 +++++++++++++---------------------- 1 file changed, 13 insertions(+), 22 deletions(-) diff --git a/stripe.go b/stripe.go index 4570fa1f55..a84297429b 100644 --- a/stripe.go +++ b/stripe.go @@ -280,32 +280,31 @@ type BackendImplementation struct { requestMetricsBuffer chan requestMetrics } -type unmarshalTargeter interface { - GetUnmarshalTarget() interface{} -} - type lastResponseSetterWrapper struct { + LastResponseSetter f func(*APIResponse) - unmarshalTarget LastResponseSetter } func (l *lastResponseSetterWrapper) SetLastResponse(response *APIResponse) { l.f(response) + l.LastResponseSetter.SetLastResponse(response) } -func (l *lastResponseSetterWrapper) GetUnmarshalTarget() interface{} { - return l.unmarshalTarget + +func (l *lastResponseSetterWrapper) UnmarshalJSON(b []byte) error { + return json.Unmarshal(b, l.LastResponseSetter) } type streamingLastResponseSetterWrapper struct { + StreamingLastResponseSetter f func(*StreamingAPIResponse) - unmarshalTarget StreamingLastResponseSetter } func (l *streamingLastResponseSetterWrapper) SetLastResponse(response *StreamingAPIResponse) { l.f(response) + l.StreamingLastResponseSetter.SetLastResponse(response) } -func (l *streamingLastResponseSetterWrapper) GetUnmarshalTarget() interface{} { - return l.unmarshalTarget +func (l *streamingLastResponseSetterWrapper) UnmarshalJSON(b []byte) error { + return json.Unmarshal(b, l.StreamingLastResponseSetter) } func extractParams(params ParamsContainer) (*form.Values, *Params, error) { @@ -380,15 +379,14 @@ func (s *BackendImplementation) CallStreaming(method, path, key string, params P } responseSetter := streamingLastResponseSetterWrapper{ + v, func(response *StreamingAPIResponse) { var usage []string if commonParams != nil { usage = commonParams.usage } s.maybeEnqueueTelemetryMetrics(response.RequestID, response.duration, usage) - v.SetLastResponse(response) }, - v, } if err := s.DoStreaming(req, bodyBuffer, &responseSetter); err != nil { @@ -434,7 +432,8 @@ func (s *BackendImplementation) CallRaw(method, path, key string, form *form.Val } responseSetter := lastResponseSetterWrapper{ - f: func(response *APIResponse) { + v, + func(response *APIResponse) { var usage []string if params != nil { usage = params.usage @@ -442,7 +441,6 @@ func (s *BackendImplementation) CallRaw(method, path, key string, form *form.Val s.maybeEnqueueTelemetryMetrics(response.RequestID, response.duration, usage) v.SetLastResponse(response) }, - unmarshalTarget: v, } if err := s.Do(req, bodyBuffer, &responseSetter); err != nil { @@ -741,15 +739,8 @@ func (s *BackendImplementation) Do(req *http.Request, body *bytes.Buffer, v Last } resBody := result.([]byte) s.LeveledLogger.Debugf("Response: %s", string(resBody)) - var unmarshalTarget interface{} - targeter, ok := v.(unmarshalTargeter) - if ok { - unmarshalTarget = targeter.GetUnmarshalTarget() - } else { - unmarshalTarget = v - } - err = s.UnmarshalJSONVerbose(res.StatusCode, resBody, unmarshalTarget) + err = s.UnmarshalJSONVerbose(res.StatusCode, resBody, v) v.SetLastResponse(newAPIResponse(res, resBody, requestDuration)) return err } From 0a647ba8b86e43ff80de3fe374517ded87bf95ca Mon Sep 17 00:00:00 2001 From: Richard Marmorstein Date: Thu, 7 Dec 2023 10:50:07 -0800 Subject: [PATCH 4/9] Exercise .InternalSetUsage --- params.go | 4 ++-- stripe_test.go | 26 ++++++++++++++++---------- 2 files changed, 18 insertions(+), 12 deletions(-) diff --git a/params.go b/params.go index 8dc45e0dd6..d9ded2c27f 100644 --- a/params.go +++ b/params.go @@ -212,9 +212,9 @@ func (p *Params) AddExpand(f string) { p.Expand = append(p.Expand, &f) } -// SetUsage sets the usage field on the Params struct. +// InternalSetUsage sets the usage field on the Params struct. // Unstable: for internal stripe-go usage only. -func (p *Params) SetUsage(usage []string) { +func (p *Params) InternalSetUsage(usage []string) { p.usage = usage } diff --git a/stripe_test.go b/stripe_test.go index a8e92eb5a3..3ec8c07a28 100644 --- a/stripe_test.go +++ b/stripe_test.go @@ -436,7 +436,7 @@ func TestDo_LastResponsePopulated(t *testing.T) { } // Test that telemetry metrics are not sent by default -func TestDo_TelemetryDisabled(t *testing.T) { +func TestCall_TelemetryDisabled(t *testing.T) { type testServerResponse struct { APIResource Message string `json:"message"` @@ -487,17 +487,12 @@ func TestDo_TelemetryDisabled(t *testing.T) { // Test that telemetry metrics are sent on subsequent requests when // EnableTelemetry = true. -func TestDo_TelemetryEnabled(t *testing.T) { +func TestCall_TelemetryEnabled(t *testing.T) { type testServerResponse struct { APIResource Message string `json:"message"` } - type requestMetrics struct { - RequestDurationMS int `json:"request_duration_ms"` - RequestID string `json:"request_id"` - } - type requestTelemetry struct { LastRequestMetrics requestMetrics `json:"last_request_metrics"` } @@ -505,6 +500,7 @@ func TestDo_TelemetryEnabled(t *testing.T) { message := "Hello, client." requestNum := 0 + var telemetry requestTelemetry testServer := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { requestNum++ @@ -518,13 +514,12 @@ func TestDo_TelemetryEnabled(t *testing.T) { assert.True(t, len(telemetryStr) > 0, "telemetryStr should not be empty") // the telemetry should properly unmarshal into RequestTelemetry - var telemetry requestTelemetry err := json.Unmarshal([]byte(telemetryStr), &telemetry) assert.NoError(t, err) // the second request should include the metrics for the first request assert.Equal(t, telemetry.LastRequestMetrics.RequestID, "req_1") - assert.True(t, telemetry.LastRequestMetrics.RequestDurationMS > 20, + assert.True(t, *telemetry.LastRequestMetrics.RequestDurationMS > 20, "request_duration_ms should be > 20ms") default: assert.Fail(t, "Should not have reached request %v", requestNum) @@ -551,9 +546,17 @@ func TestDo_TelemetryEnabled(t *testing.T) { }, ).(*BackendImplementation) + type myCreateParams struct { + Params `form:"*"` + Foo string `form:"foo"` + } + params := &myCreateParams{ + Foo: "bar", + } + params.InternalSetUsage([]string{"llama", "bufo"}) for i := 0; i < 2; i++ { var response testServerResponse - err := backend.Call("get", "/hello", "sk_test_xyz", nil, &response) + err := backend.Call("get", "/hello", "sk_test_xyz", params, &response) assert.NoError(t, err) assert.Equal(t, message, response.Message) @@ -561,6 +564,9 @@ func TestDo_TelemetryEnabled(t *testing.T) { // We should have seen exactly two requests. assert.Equal(t, 2, requestNum) + // The telemetry in the second request should contain the + // expected usage + assert.Equal(t, telemetry.LastRequestMetrics.Usage, []string{"llama", "bufo"}) } // This test does not perform any super valuable assertions - instead, it checks From a5a8ce6942c1321ac47aa2f6b4a36435931d8b98 Mon Sep 17 00:00:00 2001 From: Richard Marmorstein Date: Thu, 7 Dec 2023 11:40:29 -0800 Subject: [PATCH 5/9] readme --- README.md | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/README.md b/README.md index fbb41baffb..79aa5de0ff 100644 --- a/README.md +++ b/README.md @@ -458,10 +458,11 @@ This information is passed along when the library makes calls to the Stripe API. Note that while `Name` is always required, `URL` and `Version` are optional. -### Request latency telemetry +### Telemetry -By default, the library sends request latency telemetry to Stripe. These -numbers help Stripe improve the overall latency of its API for all users. +By default, the library sends telemetry to Stripe regarding request latency and feature usage. These +numbers help Stripe improve the overall latency of its API for all users, and +improve popular features. You can disable this behavior if you prefer: From 7dc1293a8ed763a403179c245c290c0695ad6e84 Mon Sep 17 00:00:00 2001 From: Richard Marmorstein Date: Tue, 12 Dec 2023 13:08:51 -0800 Subject: [PATCH 6/9] Specialize --- stripe.go | 33 ++++++++++++++++----------------- 1 file changed, 16 insertions(+), 17 deletions(-) diff --git a/stripe.go b/stripe.go index a84297429b..d4e6ee244d 100644 --- a/stripe.go +++ b/stripe.go @@ -280,18 +280,23 @@ type BackendImplementation struct { requestMetricsBuffer chan requestMetrics } -type lastResponseSetterWrapper struct { +type metricsResponseSetter struct { LastResponseSetter - f func(*APIResponse) + backend *BackendImplementation + params *Params } -func (l *lastResponseSetterWrapper) SetLastResponse(response *APIResponse) { - l.f(response) - l.LastResponseSetter.SetLastResponse(response) +func (s *metricsResponseSetter) SetLastResponse (response *APIResponse) { + var usage []string + if s.params != nil { + usage = s.params.usage + } + s.backend.maybeEnqueueTelemetryMetrics(response.RequestID, response.duration, usage) + s.LastResponseSetter.SetLastResponse(response) } -func (l *lastResponseSetterWrapper) UnmarshalJSON(b []byte) error { - return json.Unmarshal(b, l.LastResponseSetter) +func (s *metricsResponseSetter) UnmarshalJSON(b []byte) error { + return json.Unmarshal(b, s.LastResponseSetter) } type streamingLastResponseSetterWrapper struct { @@ -431,16 +436,10 @@ func (s *BackendImplementation) CallRaw(method, path, key string, form *form.Val return err } - responseSetter := lastResponseSetterWrapper{ - v, - func(response *APIResponse) { - var usage []string - if params != nil { - usage = params.usage - } - s.maybeEnqueueTelemetryMetrics(response.RequestID, response.duration, usage) - v.SetLastResponse(response) - }, + responseSetter := metricsResponseSetter{ + LastResponseSetter: v, + backend: s, + params: params, } if err := s.Do(req, bodyBuffer, &responseSetter); err != nil { From 0d371a0d70c96a1d369d8dda5c7839149aacc643 Mon Sep 17 00:00:00 2001 From: Richard Marmorstein Date: Tue, 12 Dec 2023 14:10:39 -0800 Subject: [PATCH 7/9] Move assert --- stripe_test.go | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/stripe_test.go b/stripe_test.go index 3ec8c07a28..9d1f124a94 100644 --- a/stripe_test.go +++ b/stripe_test.go @@ -521,6 +521,10 @@ func TestCall_TelemetryEnabled(t *testing.T) { assert.Equal(t, telemetry.LastRequestMetrics.RequestID, "req_1") assert.True(t, *telemetry.LastRequestMetrics.RequestDurationMS > 20, "request_duration_ms should be > 20ms") + + // The telemetry in the second request should contain the + // expected usage + assert.Equal(t, telemetry.LastRequestMetrics.Usage, []string{"llama", "bufo"}) default: assert.Fail(t, "Should not have reached request %v", requestNum) } @@ -564,9 +568,6 @@ func TestCall_TelemetryEnabled(t *testing.T) { // We should have seen exactly two requests. assert.Equal(t, 2, requestNum) - // The telemetry in the second request should contain the - // expected usage - assert.Equal(t, telemetry.LastRequestMetrics.Usage, []string{"llama", "bufo"}) } // This test does not perform any super valuable assertions - instead, it checks From 79d3cc347dda4844539819a8ce996d12e1518f82 Mon Sep 17 00:00:00 2001 From: Richard Marmorstein Date: Tue, 12 Dec 2023 14:14:57 -0800 Subject: [PATCH 8/9] Fix nit --- stripe_test.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/stripe_test.go b/stripe_test.go index 9d1f124a94..e2dbd4ec5e 100644 --- a/stripe_test.go +++ b/stripe_test.go @@ -500,7 +500,6 @@ func TestCall_TelemetryEnabled(t *testing.T) { message := "Hello, client." requestNum := 0 - var telemetry requestTelemetry testServer := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { requestNum++ @@ -513,6 +512,7 @@ func TestCall_TelemetryEnabled(t *testing.T) { case 2: assert.True(t, len(telemetryStr) > 0, "telemetryStr should not be empty") + var telemetry requestTelemetry // the telemetry should properly unmarshal into RequestTelemetry err := json.Unmarshal([]byte(telemetryStr), &telemetry) assert.NoError(t, err) From 6d40270033403405040aa5b4f0c63c08ef1b21ec Mon Sep 17 00:00:00 2001 From: Richard Marmorstein Date: Tue, 12 Dec 2023 14:25:40 -0800 Subject: [PATCH 9/9] Format --- stripe.go | 10 +++++----- stripe_test.go | 4 ++-- 2 files changed, 7 insertions(+), 7 deletions(-) diff --git a/stripe.go b/stripe.go index d4e6ee244d..7e78fca97a 100644 --- a/stripe.go +++ b/stripe.go @@ -283,10 +283,10 @@ type BackendImplementation struct { type metricsResponseSetter struct { LastResponseSetter backend *BackendImplementation - params *Params + params *Params } -func (s *metricsResponseSetter) SetLastResponse (response *APIResponse) { +func (s *metricsResponseSetter) SetLastResponse(response *APIResponse) { var usage []string if s.params != nil { usage = s.params.usage @@ -301,7 +301,7 @@ func (s *metricsResponseSetter) UnmarshalJSON(b []byte) error { type streamingLastResponseSetterWrapper struct { StreamingLastResponseSetter - f func(*StreamingAPIResponse) + f func(*StreamingAPIResponse) } func (l *streamingLastResponseSetterWrapper) SetLastResponse(response *StreamingAPIResponse) { @@ -438,8 +438,8 @@ func (s *BackendImplementation) CallRaw(method, path, key string, form *form.Val responseSetter := metricsResponseSetter{ LastResponseSetter: v, - backend: s, - params: params, + backend: s, + params: params, } if err := s.Do(req, bodyBuffer, &responseSetter); err != nil { diff --git a/stripe_test.go b/stripe_test.go index e2dbd4ec5e..0371f5380f 100644 --- a/stripe_test.go +++ b/stripe_test.go @@ -512,7 +512,7 @@ func TestCall_TelemetryEnabled(t *testing.T) { case 2: assert.True(t, len(telemetryStr) > 0, "telemetryStr should not be empty") - var telemetry requestTelemetry + var telemetry requestTelemetry // the telemetry should properly unmarshal into RequestTelemetry err := json.Unmarshal([]byte(telemetryStr), &telemetry) assert.NoError(t, err) @@ -552,7 +552,7 @@ func TestCall_TelemetryEnabled(t *testing.T) { type myCreateParams struct { Params `form:"*"` - Foo string `form:"foo"` + Foo string `form:"foo"` } params := &myCreateParams{ Foo: "bar",