Skip to content

Commit 6d0c02b

Browse files
Merge pull request #15 from speakeasy-api/sdk-parity
fix: test parity with the test suite
2 parents 8a0d0b0 + a15a440 commit 6d0c02b

30 files changed

+1240
-838
lines changed

.golangci.yaml

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -61,5 +61,7 @@ linters-settings:
6161
arguments: [["API"], []]
6262
stylecheck:
6363
checks: ["all", "-ST1000", "-ST1003"]
64+
cyclop:
65+
max-complexity: 15
6466
run:
6567
go: "1.14"

capture.go

Lines changed: 49 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,8 @@ import (
99
"io/ioutil"
1010
"net/http"
1111
"net/http/httptest"
12+
"sort"
13+
"strconv"
1214
"time"
1315

1416
"github.com/chromedp/cdproto/har"
@@ -143,13 +145,19 @@ func (s *Speakeasy) buildHarFile(ctx context.Context, cw *captureWriter, r *http
143145
Response: s.getHarResponse(ctx, cw, r, startTime),
144146
Connection: r.URL.Port(),
145147
ServerIPAddress: r.URL.Hostname(),
148+
Cache: &har.Cache{},
149+
Timings: &har.Timings{
150+
Send: -1,
151+
Wait: -1,
152+
Receive: -1,
153+
},
146154
},
147155
},
148156
},
149157
}
150158
}
151159

152-
//nolint:cyclop,funlen
160+
//nolint:funlen
153161
func (s *Speakeasy) getHarRequest(ctx context.Context, cw *captureWriter, r *http.Request) *har.Request {
154162
reqHeaders := []*har.NameValuePair{}
155163
for k, v := range r.Header {
@@ -158,6 +166,10 @@ func (s *Speakeasy) getHarRequest(ctx context.Context, cw *captureWriter, r *htt
158166
}
159167
}
160168

169+
sort.SliceStable(reqHeaders, func(i, j int) bool {
170+
return reqHeaders[i].Name < reqHeaders[j].Name
171+
})
172+
161173
reqQueryParams := []*har.NameValuePair{}
162174

163175
for k, v := range r.URL.Query() {
@@ -200,24 +212,30 @@ func (s *Speakeasy) getHarRequest(ctx context.Context, cw *captureWriter, r *htt
200212

201213
postData = &har.PostData{
202214
MimeType: reqContentType,
215+
Params: []*har.Param{},
203216
Text: bodyText,
204-
Params: []*har.Param{}, // We don't parse the body here to populate this
205217
}
206218
}
207219

220+
var bodySize int64 = -1
221+
if postData != nil {
222+
bodySize = r.ContentLength
223+
}
224+
208225
return &har.Request{
209226
Method: r.Method,
210227
URL: r.URL.String(),
211228
Headers: reqHeaders,
212229
QueryString: reqQueryParams,
213-
BodySize: r.ContentLength,
230+
BodySize: bodySize,
214231
PostData: postData,
215232
HTTPVersion: r.Proto,
216233
Cookies: reqCookies,
217234
HeadersSize: int64(headerSize),
218235
}
219236
}
220237

238+
//nolint:funlen
221239
func (s *Speakeasy) getHarResponse(ctx context.Context, cw *captureWriter, r *http.Request, startTime time.Time) *har.Response {
222240
resHeaders := []*har.NameValuePair{}
223241

@@ -233,23 +251,42 @@ func (s *Speakeasy) getHarResponse(ctx context.Context, cw *captureWriter, r *ht
233251
}
234252
}
235253

254+
sort.SliceStable(resHeaders, func(i, j int) bool {
255+
return resHeaders[i].Name < resHeaders[j].Name
256+
})
257+
236258
resCookies := getHarCookies(cookieParser.Cookies(), startTime)
237259

238260
resContentType := cw.origResW.Header().Get("Content-Type")
239261
if resContentType == "" {
240262
resContentType = "application/octet-stream" // default http content type
241263
}
242264

243-
bodyText := "--dropped--"
244-
contentBodySize := 0
245-
if cw.IsResValid() {
246-
bodyText = cw.GetResBuffer().String()
247-
contentBodySize = cw.GetResBuffer().Len()
248-
}
249-
250-
bodySize := cw.GetResponseSize()
265+
bodyText := ""
266+
var bodySize int64 = -1
267+
contentBodySize := -1
268+
//nolint:nestif
251269
if cw.GetStatus() == http.StatusNotModified {
252270
bodySize = 0
271+
} else {
272+
if !cw.IsResValid() {
273+
bodyText = "--dropped--"
274+
} else {
275+
bodyText = cw.GetResBuffer().String()
276+
if cw.GetResBuffer().Len() > 0 {
277+
contentBodySize = cw.GetResBuffer().Len()
278+
}
279+
}
280+
281+
contentLength := cw.origResW.Header().Get("Content-Length")
282+
if contentLength != "" {
283+
var err error
284+
//nolint:gomnd
285+
bodySize, err = strconv.ParseInt(contentLength, 10, 64)
286+
if err != nil {
287+
bodySize = -1
288+
}
289+
}
253290
}
254291

255292
b := bytes.NewBuffer([]byte{})
@@ -273,7 +310,7 @@ func (s *Speakeasy) getHarResponse(ctx context.Context, cw *captureWriter, r *ht
273310
},
274311
RedirectURL: cw.origResW.Header().Get("Location"),
275312
HeadersSize: int64(headerSize),
276-
BodySize: int64(bodySize),
313+
BodySize: bodySize,
277314
}
278315
}
279316

middleware_test.go

Lines changed: 32 additions & 27 deletions
Original file line numberDiff line numberDiff line change
@@ -38,19 +38,23 @@ func TestMain(m *testing.M) {
3838
os.Exit(m.Run())
3939
}
4040

41+
type header struct {
42+
Key string `json:"key"`
43+
Values []string `json:"values"`
44+
}
4145
type fields struct {
4246
MaxCaptureSize int `json:"max_capture_size,omitempty"`
4347
}
4448
type args struct {
45-
Method string `json:"method"`
46-
URL string `json:"url"`
47-
Headers map[string][]string `json:"headers"`
48-
Body string `json:"body"`
49-
RequestStartTime time.Time `json:"request_start_time"`
50-
ElapsedTime int `json:"elapsed_time"`
51-
ResponseStatus int `json:"response_status"`
52-
ResponseBody string `json:"response_body"`
53-
ResponseHeaders map[string][]string `json:"response_headers"`
49+
Method string `json:"method"`
50+
URL string `json:"url"`
51+
Headers []header `json:"headers"`
52+
Body string `json:"body"`
53+
RequestStartTime time.Time `json:"request_start_time"`
54+
ElapsedTime int `json:"elapsed_time"`
55+
ResponseStatus int `json:"response_status"`
56+
ResponseBody string `json:"response_body"`
57+
ResponseHeaders []header `json:"response_headers"`
5458
}
5559
type test struct {
5660
Name string `json:"name"`
@@ -135,16 +139,17 @@ func TestSpeakeasy_Middleware_Capture_Success(t *testing.T) {
135139

136140
assert.Equal(t, testApiID, req.ApiId)
137141
assert.Equal(t, testVersionID, req.VersionId)
142+
138143
assert.Equal(t, tt.WantHAR, req.Har)
139144
captured = true
140145
wg.Done()
141146
}),
142147
})
143148

144149
h := sdkInstance.Middleware(http.HandlerFunc(func(w http.ResponseWriter, req *http.Request) {
145-
for k, v := range tt.Args.ResponseHeaders {
146-
for _, vv := range v {
147-
w.Header().Add(k, vv)
150+
for _, header := range tt.Args.ResponseHeaders {
151+
for _, val := range header.Values {
152+
w.Header().Add(header.Key, val)
148153
}
149154
}
150155

@@ -176,9 +181,9 @@ func TestSpeakeasy_Middleware_Capture_Success(t *testing.T) {
176181
}
177182
assert.NoError(t, err)
178183

179-
for k, v := range tt.Args.Headers {
180-
for _, vv := range v {
181-
req.Header.Add(k, vv)
184+
for _, header := range tt.Args.Headers {
185+
for _, val := range header.Values {
186+
req.Header.Add(header.Key, val)
182187
}
183188
}
184189

@@ -463,9 +468,9 @@ func TestSpeakeasy_GinMiddleware_Success(t *testing.T) {
463468
r.Use(sdkInstance.GinMiddleware)
464469

465470
r.Any("/*path", func(ctx *gin.Context) {
466-
for k, v := range tt.Args.ResponseHeaders {
467-
for _, vv := range v {
468-
ctx.Writer.Header().Add(k, vv)
471+
for _, header := range tt.Args.ResponseHeaders {
472+
for _, val := range header.Values {
473+
ctx.Writer.Header().Add(header.Key, val)
469474
}
470475
}
471476

@@ -497,9 +502,9 @@ func TestSpeakeasy_GinMiddleware_Success(t *testing.T) {
497502
}
498503
assert.NoError(t, err)
499504

500-
for k, v := range tt.Args.Headers {
501-
for _, vv := range v {
502-
req.Header.Add(k, vv)
505+
for _, header := range tt.Args.Headers {
506+
for _, val := range header.Values {
507+
req.Header.Add(header.Key, val)
503508
}
504509
}
505510

@@ -647,9 +652,9 @@ func TestSpeakeasy_EchoMiddleware_Success(t *testing.T) {
647652
r.Use(sdkInstance.EchoMiddleware)
648653

649654
r.Any("/*", func(c echo.Context) error {
650-
for k, v := range tt.Args.ResponseHeaders {
651-
for _, vv := range v {
652-
c.Response().Header().Add(k, vv)
655+
for _, header := range tt.Args.ResponseHeaders {
656+
for _, val := range header.Values {
657+
c.Response().Header().Add(header.Key, val)
653658
}
654659
}
655660

@@ -683,9 +688,9 @@ func TestSpeakeasy_EchoMiddleware_Success(t *testing.T) {
683688
}
684689
assert.NoError(t, err)
685690

686-
for k, v := range tt.Args.Headers {
687-
for _, vv := range v {
688-
req.Header.Add(k, vv)
691+
for _, header := range tt.Args.Headers {
692+
for _, val := range header.Values {
693+
req.Header.Add(header.Key, val)
689694
}
690695
}
691696

speakeasy.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -27,7 +27,7 @@ const (
2727
)
2828

2929
var (
30-
speakeasyVersion = "1.1.0" // TODO get this from CI
30+
speakeasyVersion = "1.1.2" // TODO get this from CI
3131
serverURL = "grpc.prod.speakeasyapi.dev:443"
3232

3333
defaultInstance *Speakeasy
Lines changed: 13 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,15 @@
11
{
2-
"name": "captures basic request and no response Body",
3-
"fields": {
4-
"max_capture_size": 9437184
5-
},
6-
"args": {
7-
"method": "GET",
8-
"url": "http://test.com:8080/test"
9-
}
2+
"name": "captures basic request and no response body",
3+
"fields": {
4+
"max_capture_size": 9437184
5+
},
6+
"args": {
7+
"method": "GET",
8+
"url": "http://test.com:8080/test",
9+
"headers": [
10+
{ "key": "host", "values": ["test.com"] },
11+
{ "key": "accept-encoding", "values": ["gzip, deflate"] },
12+
{ "key": "connection", "values": ["close"] }
13+
]
14+
}
1015
}
Lines changed: 57 additions & 40 deletions
Original file line numberDiff line numberDiff line change
@@ -1,44 +1,61 @@
11
{
2-
"log": {
3-
"version": "1.2",
4-
"creator": {
5-
"name": "speakeasy-go-sdk",
6-
"version": "1.1.0"
7-
},
8-
"entries": [
2+
"log": {
3+
"version": "1.2",
4+
"creator": {
5+
"name": "speakeasy-go-sdk",
6+
"version": "1.1.2"
7+
},
8+
"entries": [
9+
{
10+
"startedDateTime": "2020-01-01T00:00:00Z",
11+
"time": 1,
12+
"request": {
13+
"method": "GET",
14+
"url": "http://test.com:8080/test",
15+
"httpVersion": "HTTP/1.1",
16+
"cookies": [],
17+
"headers": [
18+
{
19+
"name": "Accept-Encoding",
20+
"value": "gzip, deflate"
21+
},
22+
{
23+
"name": "Connection",
24+
"value": "close"
25+
},
926
{
10-
"startedDateTime": "2020-01-01T00:00:00Z",
11-
"time": 1,
12-
"request": {
13-
"method": "GET",
14-
"url": "http://test.com:8080/test",
15-
"httpVersion": "HTTP/1.1",
16-
"cookies": [],
17-
"headers": [],
18-
"queryString": [],
19-
"headersSize": 0,
20-
"bodySize": 0
21-
},
22-
"response": {
23-
"status": 200,
24-
"statusText": "OK",
25-
"httpVersion": "HTTP/1.1",
26-
"cookies": [],
27-
"headers": [],
28-
"content": {
29-
"size": 0,
30-
"mimeType": "application/octet-stream"
31-
},
32-
"redirectURL": "",
33-
"headersSize": 0,
34-
"bodySize": 0
35-
},
36-
"cache": null,
37-
"timings": null,
38-
"serverIPAddress": "test.com",
39-
"connection": "8080"
27+
"name": "Host",
28+
"value": "test.com"
4029
}
41-
],
42-
"comment": "request capture for http://test.com:8080/test"
43-
}
30+
],
31+
"queryString": [],
32+
"headersSize": 67,
33+
"bodySize": -1
34+
},
35+
"response": {
36+
"status": 200,
37+
"statusText": "OK",
38+
"httpVersion": "HTTP/1.1",
39+
"cookies": [],
40+
"headers": [],
41+
"content": {
42+
"size": -1,
43+
"mimeType": "application/octet-stream"
44+
},
45+
"redirectURL": "",
46+
"headersSize": 0,
47+
"bodySize": -1
48+
},
49+
"cache": {},
50+
"timings": {
51+
"send": -1,
52+
"wait": -1,
53+
"receive": -1
54+
},
55+
"serverIPAddress": "test.com",
56+
"connection": "8080"
57+
}
58+
],
59+
"comment": "request capture for http://test.com:8080/test"
60+
}
4461
}

0 commit comments

Comments
 (0)