Codebase list golang-github-opentracing-contrib-go-stdlib / upstream/0.0_git20190519.cf7a6c9
Add InjectSpanContext ClientOption. (#44) * Add InjectSpanContext ClientOption. Fixes #43. * Document default behaviour. * Add TestInjectSpanContext * Fix doc NV authored 4 years ago Yuri Shkuro committed 4 years ago
2 changed file(s) with 86 addition(s) and 6 deletion(s). Raw diff Collapse all Expand all
3030 }
3131
3232 type clientOptions struct {
33 operationName string
34 componentName string
35 disableClientTrace bool
36 spanObserver func(span opentracing.Span, r *http.Request)
33 operationName string
34 componentName string
35 disableClientTrace bool
36 disableInjectSpanContext bool
37 spanObserver func(span opentracing.Span, r *http.Request)
3738 }
3839
3940 // ClientOption contols the behavior of TraceRequest.
6061 func ClientTrace(enabled bool) ClientOption {
6162 return func(options *clientOptions) {
6263 options.disableClientTrace = !enabled
64 }
65 }
66
67 // InjectSpanContext returns a ClientOption that turns on or off
68 // injection of the Span context in the request HTTP headers.
69 // If this option is not used, the default behaviour is to
70 // inject the span context.
71 func InjectSpanContext(enabled bool) ClientOption {
72 return func(options *clientOptions) {
73 options.disableInjectSpanContext = !enabled
6374 }
6475 }
6576
150161 ext.HTTPUrl.Set(tracer.sp, req.URL.String())
151162 tracer.opts.spanObserver(tracer.sp, req)
152163
153 carrier := opentracing.HTTPHeadersCarrier(req.Header)
154 tracer.sp.Tracer().Inject(tracer.sp.Context(), opentracing.HTTPHeaders, carrier)
164 if !tracer.opts.disableInjectSpanContext {
165 carrier := opentracing.HTTPHeadersCarrier(req.Header)
166 tracer.sp.Tracer().Inject(tracer.sp.Context(), opentracing.HTTPHeaders, carrier)
167 }
168
155169 resp, err := rt.RoundTrip(req)
156170
157171 if err != nil {
133133 }
134134 }
135135
136 func TestInjectSpanContext(t *testing.T) {
137 tests := []struct {
138 name string
139 expectContextPropagation bool
140 opts []ClientOption
141 }{
142 {name: "Default", expectContextPropagation: true, opts: nil},
143 {name: "True", expectContextPropagation: true, opts: []ClientOption{InjectSpanContext(true)}},
144 {name: "False", expectContextPropagation: false, opts: []ClientOption{InjectSpanContext(false)}},
145 }
146
147 for _, tt := range tests {
148 t.Run(tt.name, func(t *testing.T) {
149 var handlerCalled bool
150 srv := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
151 handlerCalled = true
152 srvTr := mocktracer.New()
153 ctx, err := srvTr.Extract(opentracing.HTTPHeaders, opentracing.HTTPHeadersCarrier(r.Header))
154
155 if err != nil && tt.expectContextPropagation {
156 t.Fatal(err)
157 }
158
159 if tt.expectContextPropagation {
160 if err != nil || ctx == nil {
161 t.Fatal("expected propagation but unable to extract")
162 }
163 } else {
164 // Expect "opentracing: SpanContext not found in Extract carrier" when not injected
165 // Can't check ctx directly, because it gets set to emptyContext
166 if err == nil {
167 t.Fatal("unexpected propagation")
168 }
169 }
170 }))
171
172 tr := mocktracer.New()
173 span := tr.StartSpan("root")
174
175 req, err := http.NewRequest("GET", srv.URL, nil)
176 if err != nil {
177 t.Fatal(err)
178 }
179 req = req.WithContext(opentracing.ContextWithSpan(req.Context(), span))
180
181 req, ht := TraceRequest(tr, req, tt.opts...)
182
183 client := &http.Client{Transport: &Transport{}}
184 resp, err := client.Do(req)
185 if err != nil {
186 t.Fatal(err)
187 }
188 _ = resp.Body.Close()
189
190 ht.Finish()
191 span.Finish()
192
193 srv.Close()
194
195 if !handlerCalled {
196 t.Fatal("server handler never called")
197 }
198 })
199 }
200 }
201
136202 func makeTags(keyVals ...interface{}) map[string]interface{} {
137203 result := make(map[string]interface{}, len(keyVals)/2)
138204 for i := 0; i < len(keyVals)-1; i += 2 {