@@ -84,7 +84,8 @@ func TestTracingIngressSpan(t *testing.T) {
84
84
})
85
85
defer s .Close ()
86
86
87
- doc := fmt .Sprintf (`hello: Path("/hello") -> setPath("/bye") -> setQuery("void") -> "%s"` , s .URL )
87
+ routeID := "ingressRoute"
88
+ doc := fmt .Sprintf (`%s: Path("/hello") -> setPath("/bye") -> setQuery("void") -> "%s"` , routeID , s .URL )
88
89
89
90
tracer := mocktracer .New ()
90
91
params := Params {
@@ -126,6 +127,7 @@ func TestTracingIngressSpan(t *testing.T) {
126
127
127
128
verifyTag (t , span , SpanKindTag , SpanKindServer )
128
129
verifyTag (t , span , ComponentTag , "skipper" )
130
+ verifyTag (t , span , SkipperRouteIDTag , routeID )
129
131
// to save memory we dropped the URL tag from ingress span
130
132
//verifyTag(t, span, HTTPUrlTag, "/hello?world") // For server requests there is no scheme://host:port, see https://golang.org/pkg/net/http/#Request
131
133
verifyTag (t , span , HTTPMethodTag , "GET" )
@@ -137,6 +139,139 @@ func TestTracingIngressSpan(t *testing.T) {
137
139
verifyHasTag (t , span , HTTPRemoteIPTag )
138
140
}
139
141
142
+ func TestTracingIngressSpanShunt (t * testing.T ) {
143
+ routeID := "ingressShuntRoute"
144
+ doc := fmt .Sprintf (`%s: Path("/hello") -> setPath("/bye") -> setQuery("void") -> status(205) -> <shunt>` , routeID )
145
+
146
+ tracer := mocktracer .New ()
147
+ params := Params {
148
+ OpenTracing : & OpenTracingParams {
149
+ Tracer : tracer ,
150
+ },
151
+ Flags : FlagsNone ,
152
+ }
153
+
154
+ t .Setenv ("HOSTNAME" , "ingress-shunt.tracing.test" )
155
+
156
+ tp , err := newTestProxyWithParams (doc , params )
157
+ if err != nil {
158
+ t .Fatal (err )
159
+ }
160
+ defer tp .close ()
161
+
162
+ ps := httptest .NewServer (tp .proxy )
163
+ defer ps .Close ()
164
+
165
+ req , err := http .NewRequest ("GET" , ps .URL + "/hello?world" , nil )
166
+ if err != nil {
167
+ t .Fatal (err )
168
+ }
169
+ req .Header .Set ("X-Flow-Id" , "test-flow-id" )
170
+
171
+ rsp , err := ps .Client ().Do (req )
172
+ if err != nil {
173
+ t .Fatal (err )
174
+ }
175
+ defer rsp .Body .Close ()
176
+ io .Copy (io .Discard , rsp .Body )
177
+
178
+ // client may get response before proxy finishes span
179
+ time .Sleep (10 * time .Millisecond )
180
+
181
+ span , ok := findSpan (tracer , "ingress" )
182
+ if ! ok {
183
+ t .Fatal ("ingress span not found" )
184
+ }
185
+
186
+ verifyTag (t , span , SpanKindTag , SpanKindServer )
187
+ verifyTag (t , span , ComponentTag , "skipper" )
188
+ verifyTag (t , span , SkipperRouteIDTag , routeID )
189
+ // to save memory we dropped the URL tag from ingress span
190
+ //verifyTag(t, span, HTTPUrlTag, "/hello?world") // For server requests there is no scheme://host:port, see https://golang.org/pkg/net/http/#Request
191
+ verifyTag (t , span , HTTPMethodTag , "GET" )
192
+ verifyTag (t , span , HostnameTag , "ingress-shunt.tracing.test" )
193
+ verifyTag (t , span , HTTPPathTag , "/hello" )
194
+ verifyTag (t , span , HTTPHostTag , ps .Listener .Addr ().String ())
195
+ verifyTag (t , span , FlowIDTag , "test-flow-id" )
196
+ verifyTag (t , span , HTTPStatusCodeTag , uint16 (205 ))
197
+ verifyHasTag (t , span , HTTPRemoteIPTag )
198
+ }
199
+
200
+ func TestTracingIngressSpanLoopback (t * testing.T ) {
201
+ shuntRouteID := "ingressShuntRoute"
202
+ loop1RouteID := "loop1Route"
203
+ loop2RouteID := "loop2Route"
204
+ routeIDs := []string {loop2RouteID , loop1RouteID , shuntRouteID }
205
+ paths := map [string ]string {
206
+ loop2RouteID : "/loop2" ,
207
+ loop1RouteID : "/loop1" ,
208
+ shuntRouteID : "/shunt" ,
209
+ }
210
+
211
+ doc := fmt .Sprintf (`
212
+ %s: Path("/shunt") -> setPath("/bye") -> setQuery("void") -> status(204) -> <shunt>;
213
+ %s: Path("/loop1") -> setPath("/shunt") -> <loopback>;
214
+ %s: Path("/loop2") -> setPath("/loop1") -> <loopback>;
215
+ ` , shuntRouteID , loop1RouteID , loop2RouteID )
216
+
217
+ tracer := mocktracer .New ()
218
+ params := Params {
219
+ OpenTracing : & OpenTracingParams {
220
+ Tracer : tracer ,
221
+ },
222
+ Flags : FlagsNone ,
223
+ }
224
+
225
+ t .Setenv ("HOSTNAME" , "ingress-loop.tracing.test" )
226
+
227
+ tp , err := newTestProxyWithParams (doc , params )
228
+ if err != nil {
229
+ t .Fatal (err )
230
+ }
231
+ defer tp .close ()
232
+
233
+ ps := httptest .NewServer (tp .proxy )
234
+ defer ps .Close ()
235
+
236
+ req , err := http .NewRequest ("GET" , ps .URL + "/loop2" , nil )
237
+ if err != nil {
238
+ t .Fatal (err )
239
+ }
240
+ req .Header .Set ("X-Flow-Id" , "test-flow-id" )
241
+
242
+ rsp , err := ps .Client ().Do (req )
243
+ if err != nil {
244
+ t .Fatal (err )
245
+ }
246
+ defer rsp .Body .Close ()
247
+ io .Copy (io .Discard , rsp .Body )
248
+ t .Logf ("got response %d" , rsp .StatusCode )
249
+
250
+ // client may get response before proxy finishes span
251
+ time .Sleep (10 * time .Millisecond )
252
+
253
+ sp , ok := findSpanByRouteID (tracer , loop2RouteID )
254
+ if ! ok {
255
+ t .Fatalf ("span for route %q not found" , loop2RouteID )
256
+ }
257
+ verifyTag (t , sp , HTTPStatusCodeTag , uint16 (204 ))
258
+
259
+ for _ , rid := range routeIDs {
260
+ span , ok := findSpanByRouteID (tracer , rid )
261
+ if ! ok {
262
+ t .Fatalf ("span for route %q not found" , rid )
263
+ }
264
+ verifyTag (t , span , SpanKindTag , SpanKindServer )
265
+ verifyTag (t , span , ComponentTag , "skipper" )
266
+ verifyTag (t , span , SkipperRouteIDTag , rid )
267
+ verifyTag (t , span , HTTPMethodTag , "GET" )
268
+ verifyTag (t , span , HostnameTag , "ingress-loop.tracing.test" )
269
+ verifyTag (t , span , HTTPPathTag , paths [rid ])
270
+ verifyTag (t , span , HTTPHostTag , ps .Listener .Addr ().String ())
271
+ verifyTag (t , span , FlowIDTag , "test-flow-id" )
272
+ }
273
+ }
274
+
140
275
func TestTracingSpanName (t * testing.T ) {
141
276
traceContent := fmt .Sprintf ("%x" , md5 .New ().Sum ([]byte (time .Now ().String ())))
142
277
s := startTestServer (nil , 0 , func (r * http.Request ) {
@@ -562,6 +697,15 @@ func findSpan(tracer *mocktracer.MockTracer, name string) (*mocktracer.MockSpan,
562
697
return nil , false
563
698
}
564
699
700
+ func findSpanByRouteID (tracer * mocktracer.MockTracer , routeID string ) (* mocktracer.MockSpan , bool ) {
701
+ for _ , s := range tracer .FinishedSpans () {
702
+ if s .Tag (SkipperRouteIDTag ) == routeID {
703
+ return s , true
704
+ }
705
+ }
706
+ return nil , false
707
+ }
708
+
565
709
func verifyTag (t * testing.T , span * mocktracer.MockSpan , name string , expected interface {}) {
566
710
t .Helper ()
567
711
if got := span .Tag (name ); got != expected {
0 commit comments