github.com/zak-blake/goa@v1.4.1/middleware/xray/wrap_doer_test.go (about) 1 package xray 2 3 import ( 4 "context" 5 "encoding/json" 6 "errors" 7 "net/http" 8 "strings" 9 "testing" 10 11 . "github.com/onsi/gomega" 12 . "github.com/onsi/gomega/gstruct" 13 ) 14 15 func TestWrapDoer(t *testing.T) { 16 RegisterTestingT(t) 17 18 var ( 19 doer = NewMockDoer() 20 ctx = context.Background() 21 ) 22 req, err := http.NewRequest("GET", "http://somehost:80/path", nil) 23 Expect(err).To(Succeed()) 24 25 t.Run(`no segment in context; success`, func(t *testing.T) { 26 RegisterTestingT(t) 27 28 doer.Expect("Do", func(c context.Context, r *http.Request) (*http.Response, error) { 29 Expect(r).To(Equal(req)) 30 Expect(c).To(Equal(ctx)) 31 return &http.Response{StatusCode: 123}, nil 32 }) 33 resp, err := WrapDoer(doer).Do(ctx, req) 34 Expect(err).To(Succeed()) 35 Expect(resp.StatusCode).To(Equal(123)) 36 Expect(doer.MetExpectations()).To(Succeed()) 37 }) 38 39 const ( 40 segmentName = "segmentName1" 41 traceID = "traceID1" 42 spanID = "spanID1" 43 ) 44 45 t.Run(`with a segment in context - successful request`, func(t *testing.T) { 46 RegisterTestingT(t) 47 48 // add an xray segment to the context 49 xrayConn := NewTestNetConn() 50 segment := NewSegment(segmentName, traceID, spanID, xrayConn) 51 ctx = WithSegment(ctx, segment) 52 53 doer.Expect("Do", func(c context.Context, r *http.Request) (*http.Response, error) { 54 Expect(r).To(Equal(req)) 55 Expect(ContextSegment(c).ParentID).To(Equal(segment.ID)) 56 return &http.Response{StatusCode: 123}, nil 57 }) 58 59 xrayConn.Expect("Write", func(b []byte) (int, error) { 60 lines := strings.Split(string(b), "\n") 61 Expect(lines).To(HaveLen(2)) 62 Expect(lines[0]).To(Equal(`{"format": "json", "version": 1}`)) 63 64 var s Segment 65 err := json.Unmarshal([]byte(lines[1]), &s) 66 Expect(err).To(Succeed()) 67 Expect(s).To(MatchFields(IgnoreMissing|IgnoreExtras, Fields{ 68 "Name": Equal("somehost:80"), 69 "Namespace": Equal("remote"), 70 "Type": Equal("subsegment"), 71 "ID": And(Not(BeEmpty()), Not(Equal(segment.ID))), // randomly generated 72 "TraceID": Equal(traceID), 73 "ParentID": Equal(spanID), 74 "Error": BeFalse(), 75 "HTTP": PointTo(MatchAllFields(Fields{ 76 "Request": Equal(&Request{Method: "GET", URL: "http://somehost:80/path"}), 77 "Response": Equal(&Response{Status: 123}), 78 })), 79 })) 80 return len(b), nil 81 }) 82 resp, err := WrapDoer(doer).Do(ctx, req) 83 Expect(err).To(Succeed()) 84 Expect(resp.StatusCode).To(Equal(123)) 85 Expect(doer.MetExpectations()).To(Succeed()) 86 Expect(xrayConn.MetExpectations()).To(Succeed()) 87 }) 88 89 t.Run(`with a segment in context - failed request`, func(t *testing.T) { 90 RegisterTestingT(t) 91 92 // add an xray segment to the context 93 xrayConn := NewTestNetConn() 94 segment := NewSegment(segmentName, traceID, spanID, xrayConn) 95 ctx = WithSegment(ctx, segment) 96 97 var ( 98 requestErr = errors.New("some request error") 99 ) 100 doer.Expect("Do", func(c context.Context, r *http.Request) (*http.Response, error) { 101 Expect(ContextSegment(c).ParentID).To(Equal(segment.ID)) 102 return nil, requestErr 103 }) 104 105 xrayConn.Expect("Write", func(b []byte) (int, error) { 106 lines := strings.Split(string(b), "\n") 107 Expect(lines).To(HaveLen(2)) 108 Expect(lines[0]).To(Equal(`{"format": "json", "version": 1}`)) 109 110 var s Segment 111 err := json.Unmarshal([]byte(lines[1]), &s) 112 Expect(err).To(Succeed()) 113 Expect(s).To(MatchFields(IgnoreMissing|IgnoreExtras, Fields{ 114 "Name": Equal("somehost:80"), 115 "Namespace": Equal("remote"), 116 "Type": Equal("subsegment"), 117 "ID": And(Not(BeEmpty()), Not(Equal(segment.ID))), // randomly generated 118 "TraceID": Equal(traceID), 119 "ParentID": Equal(spanID), 120 "Error": BeTrue(), 121 "HTTP": PointTo(MatchAllFields(Fields{ 122 "Request": Equal(&Request{Method: "GET", URL: "http://somehost:80/path"}), 123 "Response": BeNil(), 124 })), 125 })) 126 return len(b), nil 127 }) 128 _, err := WrapDoer(doer).Do(ctx, req) 129 Expect(err).To(MatchError(requestErr)) 130 131 Expect(doer.MetExpectations()).To(Succeed()) 132 Expect(xrayConn.MetExpectations()).To(Succeed()) 133 }) 134 } 135 136 type MockDoer struct { 137 *TestClientExpectation 138 } 139 140 func NewMockDoer() *MockDoer { 141 return &MockDoer{NewTestClientExpectation()} 142 } 143 144 func (m *MockDoer) Do(ctx context.Context, req *http.Request) (*http.Response, error) { 145 if e := m.Expectation("Do"); e != nil { 146 return e.(func(context.Context, *http.Request) (*http.Response, error))(ctx, req) 147 } 148 return nil, nil 149 }