@@ -20,6 +20,7 @@ import (
2020 "github.com/grafana/tempo/pkg/model/trace"
2121 "github.com/grafana/tempo/pkg/tempopb"
2222 v1_trace "github.com/grafana/tempo/pkg/tempopb/trace/v1"
23+ "github.com/grafana/tempo/pkg/util"
2324 "github.com/grafana/tempo/pkg/util/test"
2425)
2526
@@ -397,7 +398,7 @@ func TestInstanceCutCompleteTraces(t *testing.T) {
397398 instance , _ := defaultInstance (t )
398399
399400 for _ , trace := range tc .input {
400- fp := instance . tokenForTraceID (trace .traceID )
401+ fp := util . HashForTraceID (trace .traceID )
401402 instance .traces [fp ] = trace
402403 }
403404
@@ -406,12 +407,12 @@ func TestInstanceCutCompleteTraces(t *testing.T) {
406407
407408 require .Equal (t , len (tc .expectedExist ), len (instance .traces ))
408409 for _ , expectedExist := range tc .expectedExist {
409- _ , ok := instance .traces [instance . tokenForTraceID (expectedExist .traceID )]
410+ _ , ok := instance .traces [util . HashForTraceID (expectedExist .traceID )]
410411 require .True (t , ok )
411412 }
412413
413414 for _ , expectedNotExist := range tc .expectedNotExist {
414- _ , ok := instance .traces [instance . tokenForTraceID (expectedNotExist .traceID )]
415+ _ , ok := instance .traces [util . HashForTraceID (expectedNotExist .traceID )]
415416 require .False (t , ok )
416417 }
417418 })
@@ -665,6 +666,72 @@ func TestInstancePartialSuccess(t *testing.T) {
665666 assert .Equal (t , expected , result )
666667}
667668
669+ func TestFindTraceByIDNoCollisions (t * testing.T ) {
670+ ctx := context .Background ()
671+ ingester , _ , _ := defaultIngester (t , t .TempDir ())
672+ instance , err := ingester .getOrCreateInstance (testTenantID )
673+ require .NoError (t , err , "unexpected error creating new instance" )
674+
675+ // Verify that Trace IDs that collide with fnv-32 hash do not collide with fnv-64 hash
676+ hexIDs := []string {
677+ "fd5980503add11f09f80f77608c1b2da" ,
678+ "091ea7803ade11f0998a055186ee1243" ,
679+ "9e0d446036dc11f09ac04988d2097052" ,
680+ "a61ed97036dc11f0883771db3b51b1ec" ,
681+ "6b27f5501eda11f09e99db1b2c23c542" ,
682+ "6b4149b01eda11f0b0e2a966cf7ebbc8" ,
683+ "3e9582202f9a11f0afb01b7c06024bd6" ,
684+ "370db6802f9a11f0a9a212dff3125239" ,
685+ "978d70802a7311f0991f350653ef0ab4" ,
686+ "9b66da202a7311f09d292db17ccfd31a" ,
687+ "de567f703bb711f0b8c377682d1667e6" ,
688+ "dc2d0fc03bb711f091de732fcf93048c" ,
689+ }
690+
691+ ids := make ([][]byte , len (hexIDs ))
692+ for i , hexID := range hexIDs {
693+ traceID , err := util .HexStringToTraceID (hexID )
694+ require .NoError (t , err )
695+ ids [i ] = traceID
696+ }
697+
698+ multiMaxBytes := make ([]int , len (ids ))
699+ for j := range multiMaxBytes {
700+ multiMaxBytes [j ] = 1000
701+ }
702+ req := makePushBytesRequestMultiTraces (ids , multiMaxBytes )
703+ require .Equal (t , len (ids ), len (req .Traces ))
704+ response := instance .PushBytesRequest (ctx , req )
705+ errored , maxLiveCount , traceTooLargeCount := CheckPushBytesError (response )
706+
707+ require .False (t , errored )
708+ require .Equal (t , 0 , maxLiveCount )
709+ require .Equal (t , 0 , traceTooLargeCount )
710+
711+ traceResults := make ([]* tempopb.Trace , len (ids ))
712+ for i := range ids {
713+ result , err := instance .FindTraceByID (ctx , ids [i ], false )
714+ require .NoError (t , err , "error finding trace by id" )
715+ require .NotNil (t , result )
716+ require .NotNil (t , result .Trace )
717+ traceResults [i ] = result .Trace
718+ }
719+
720+ // Verify that spans do not appear in multiple traces
721+ spanIDs := map [string ]struct {}{}
722+ for _ , trace := range traceResults {
723+ for _ , resourceSpan := range trace .ResourceSpans {
724+ for _ , scopeSpan := range resourceSpan .ScopeSpans {
725+ for _ , span := range scopeSpan .Spans {
726+ _ , found := spanIDs [string (span .SpanId )]
727+ require .False (t , found , "span %s appears in multiple traces" , span .SpanId )
728+ spanIDs [string (span .SpanId )] = struct {}{}
729+ }
730+ }
731+ }
732+ }
733+ }
734+
668735func TestSortByteSlices (t * testing.T ) {
669736 numTraces := 100
670737
0 commit comments