@@ -315,6 +315,83 @@ func TestConcentratorDefaultEnv(t *testing.T) {
315315 })
316316}
317317
318+ func TestPerSpanVersionInStats (t * testing.T ) {
319+ bucketSize := int64 (500_000 )
320+ makeSpan := func (version string ) * Span {
321+ s := & Span {
322+ name : "http.request" ,
323+ start : time .Now ().UnixNano () + 3 * bucketSize ,
324+ duration : 1 ,
325+ metrics : map [string ]float64 {keyMeasured : 1 },
326+ }
327+ if version != "" {
328+ s .meta = map [string ]string {ext .Version : version }
329+ }
330+ return s
331+ }
332+
333+ t .Run ("per-span version propagates to stats payload" , func (t * testing.T ) {
334+ spanVersion := "synthtracer-20250501120000"
335+ transport := newDummyTransport ()
336+ c := newConcentrator (newTestConfigWithTransport (t , transport ), bucketSize , & statsd.NoOpClientDirect {})
337+
338+ s := makeSpan (spanVersion )
339+ ss , ok := c .newTracerStatSpan (s , nil )
340+ require .True (t , ok )
341+ c .Start ()
342+ c .In <- ss
343+ c .Stop ()
344+
345+ got := transport .Stats ()
346+ require .Len (t , got , 1 )
347+ assert .Equal (t , spanVersion , got [0 ].Version ,
348+ "per-span version tag must be used when no global version is configured" )
349+ })
350+
351+ t .Run ("falls back to global config version when span has no version tag" , func (t * testing.T ) {
352+ transport := newDummyTransport ()
353+ cfg , err := newTestConfig (withNoopInfoHTTPClient (), func (c * config ) {
354+ c .ddTransport = transport
355+ c .internalConfig .SetVersion ("global-v1.2.3" , internalconfig .OriginCode )
356+ })
357+ require .NoError (t , err )
358+ c := newConcentrator (cfg , bucketSize , & statsd.NoOpClientDirect {})
359+
360+ s := makeSpan ("" )
361+ ss , ok := c .newTracerStatSpan (s , nil )
362+ require .True (t , ok )
363+ c .Start ()
364+ c .In <- ss
365+ c .Stop ()
366+
367+ got := transport .Stats ()
368+ require .Len (t , got , 1 )
369+ assert .Equal (t , "global-v1.2.3" , got [0 ].Version )
370+ })
371+
372+ t .Run ("two spans with different versions produce separate payloads" , func (t * testing.T ) {
373+ transport := newDummyTransport ()
374+ c := newConcentrator (newTestConfigWithTransport (t , transport ), bucketSize , & statsd.NoOpClientDirect {})
375+
376+ s1 := makeSpan ("v-timestamp-1" )
377+ s2 := makeSpan ("v-timestamp-2" )
378+ ss1 , ok := c .newTracerStatSpan (s1 , nil )
379+ require .True (t , ok )
380+ ss2 , ok := c .newTracerStatSpan (s2 , nil )
381+ require .True (t , ok )
382+ c .Start ()
383+ c .In <- ss1
384+ c .In <- ss2
385+ c .Stop ()
386+
387+ got := transport .Stats ()
388+ require .Len (t , got , 2 )
389+ versions := map [string ]struct {}{got [0 ].Version : {}, got [1 ].Version : {}}
390+ assert .Contains (t , versions , "v-timestamp-1" )
391+ assert .Contains (t , versions , "v-timestamp-2" )
392+ })
393+ }
394+
318395func TestStatsIncludeHTTPMethodAndEndpoint (t * testing.T ) {
319396 uniqueMethod := "POST"
320397 uniqueEndpoint := "/__unique_endpoint__"
0 commit comments